summaryrefslogtreecommitdiffstats
path: root/korganizer
diff options
context:
space:
mode:
Diffstat (limited to 'korganizer')
-rw-r--r--korganizer/Makefile.am9
-rw-r--r--korganizer/Todo-info.text18
-rw-r--r--korganizer/aboutdata.cpp5
-rw-r--r--korganizer/actionmanager.cpp323
-rw-r--r--korganizer/actionmanager.h27
-rw-r--r--korganizer/archivedialog.cpp6
-rw-r--r--korganizer/calendarview.cpp1231
-rw-r--r--korganizer/calendarview.h185
-rw-r--r--korganizer/datenavigator.cpp124
-rw-r--r--korganizer/datenavigator.h47
-rw-r--r--korganizer/datenavigatorcontainer.cpp108
-rw-r--r--korganizer/datenavigatorcontainer.h49
-rw-r--r--korganizer/dcopcalendar.desktop1
-rw-r--r--korganizer/eventarchiver.cpp68
-rw-r--r--korganizer/eventarchiver.h16
-rw-r--r--korganizer/exportwebdialog.cpp23
-rw-r--r--korganizer/exportwebdialog.h8
-rw-r--r--korganizer/freebusymanager.cpp167
-rw-r--r--korganizer/freebusymanager.h3
-rw-r--r--korganizer/importdialog.cpp10
-rw-r--r--korganizer/importdialog.h2
-rw-r--r--korganizer/incidencechanger.cpp225
-rw-r--r--korganizer/incidencechanger.h70
-rw-r--r--korganizer/interfaces/calendar/calendardecoration.desktop1
-rw-r--r--korganizer/interfaces/calendar/calendarplugin.desktop4
-rw-r--r--korganizer/interfaces/korganizer/baseview.h95
-rw-r--r--korganizer/interfaces/korganizer/corehelper.h3
-rw-r--r--korganizer/interfaces/korganizer/incidencechangerbase.h39
-rw-r--r--korganizer/interfaces/korganizer/korganizerpart.desktop1
-rw-r--r--korganizer/interfaces/korganizer/korgprintplugin.desktop1
-rw-r--r--korganizer/interfaces/korganizer/mainwindow.h4
-rw-r--r--korganizer/journalentry.cpp19
-rw-r--r--korganizer/journalentry.h7
-rw-r--r--korganizer/kcalendariface.h3
-rw-r--r--korganizer/kdatenavigator.cpp46
-rw-r--r--korganizer/kdatenavigator.h24
-rw-r--r--korganizer/koagenda.cpp431
-rw-r--r--korganizer/koagenda.h52
-rw-r--r--korganizer/koagendaitem.cpp84
-rw-r--r--korganizer/koagendaitem.h20
-rw-r--r--korganizer/koagendaview.cpp765
-rw-r--r--korganizer/koagendaview.h50
-rw-r--r--korganizer/koattendeeeditor.cpp220
-rw-r--r--korganizer/koattendeeeditor.h16
-rw-r--r--korganizer/kocorehelper.cpp8
-rw-r--r--korganizer/kocorehelper.h1
-rw-r--r--korganizer/kocounterdialog.cpp4
-rw-r--r--korganizer/kocounterdialog.h5
-rw-r--r--korganizer/kodaymatrix.cpp41
-rw-r--r--korganizer/kodaymatrix.h9
-rw-r--r--korganizer/kodialogmanager.cpp18
-rw-r--r--korganizer/koeditoralarms.cpp138
-rw-r--r--korganizer/koeditoralarms.h6
-rw-r--r--korganizer/koeditoralarms_base.ui12
-rw-r--r--korganizer/koeditorattachments.cpp831
-rw-r--r--korganizer/koeditorattachments.h98
-rw-r--r--korganizer/koeditordetails.cpp87
-rw-r--r--korganizer/koeditordetails.h7
-rw-r--r--korganizer/koeditorfreebusy.cpp106
-rw-r--r--korganizer/koeditorfreebusy.h4
-rw-r--r--korganizer/koeditorgeneral.cpp360
-rw-r--r--korganizer/koeditorgeneral.h34
-rw-r--r--korganizer/koeditorgeneralevent.cpp76
-rw-r--r--korganizer/koeditorgeneralevent.h5
-rw-r--r--korganizer/koeditorgeneraljournal.cpp23
-rw-r--r--korganizer/koeditorgeneraljournal.h10
-rw-r--r--korganizer/koeditorgeneraltodo.cpp240
-rw-r--r--korganizer/koeditorgeneraltodo.h16
-rw-r--r--korganizer/koeditorrecurrence.cpp225
-rw-r--r--korganizer/koeditorrecurrence.h9
-rw-r--r--korganizer/koeventeditor.cpp95
-rw-r--r--korganizer/koeventeditor.h6
-rw-r--r--korganizer/koeventpopupmenu.cpp14
-rw-r--r--korganizer/koeventpopupmenu.h17
-rw-r--r--korganizer/koeventview.cpp67
-rw-r--r--korganizer/koeventview.h3
-rw-r--r--korganizer/koeventviewer.cpp106
-rw-r--r--korganizer/koeventviewer.h50
-rw-r--r--korganizer/koeventviewerdialog.cpp18
-rw-r--r--korganizer/koeventviewerdialog.h15
-rw-r--r--korganizer/koglobals.h41
-rw-r--r--korganizer/kogroupware.cpp137
-rw-r--r--korganizer/kogroupware.h21
-rw-r--r--korganizer/kogroupwareprefspage.ui20
-rw-r--r--korganizer/kohelper.cpp20
-rw-r--r--korganizer/kohelper.h6
-rw-r--r--korganizer/koincidenceeditor.cpp45
-rw-r--r--korganizer/koincidenceeditor.h38
-rw-r--r--korganizer/koincidencetooltip.cpp19
-rw-r--r--korganizer/koincidencetooltip.h14
-rw-r--r--korganizer/kojournaleditor.cpp27
-rw-r--r--korganizer/kojournaleditor.h6
-rw-r--r--korganizer/kojournalview.cpp57
-rw-r--r--korganizer/kojournalview.h6
-rw-r--r--korganizer/kolistview.cpp374
-rw-r--r--korganizer/kolistview.h30
-rw-r--r--korganizer/komailclient.cpp111
-rw-r--r--korganizer/komailclient.h7
-rw-r--r--korganizer/komonthview.cpp255
-rw-r--r--korganizer/komonthview.h30
-rw-r--r--korganizer/koprefs.cpp35
-rw-r--r--korganizer/koprefs.h1
-rw-r--r--korganizer/koprefsdialog.cpp120
-rw-r--r--korganizer/korgac/alarmdialog.cpp534
-rw-r--r--korganizer/korgac/alarmdialog.h49
-rw-r--r--korganizer/korgac/koalarmclient.cpp22
-rw-r--r--korganizer/korgac/koalarmclient.h3
-rw-r--r--korganizer/korgac/korgac.desktop2
-rw-r--r--korganizer/korgac/testalarmdlg.cpp61
-rw-r--r--korganizer/korganizer.cpp6
-rw-r--r--korganizer/korganizer.desktop8
-rw-r--r--korganizer/korganizer.h2
-rw-r--r--korganizer/korganizer.kcfg81
-rw-r--r--korganizer/korganizer_configcolors.desktop11
-rw-r--r--korganizer/korganizer_configdesignerfields.desktop5
-rw-r--r--korganizer/korganizer_configfonts.desktop11
-rw-r--r--korganizer/korganizer_configfreebusy.desktop8
-rw-r--r--korganizer/korganizer_configgroupautomation.desktop5
-rw-r--r--korganizer/korganizer_configgroupscheduling.desktop5
-rw-r--r--korganizer/korganizer_configmain.desktop11
-rw-r--r--korganizer/korganizer_configplugins.desktop8
-rw-r--r--korganizer/korganizer_configtime.desktop11
-rw-r--r--korganizer/korganizer_configviews.desktop13
-rw-r--r--korganizer/korganizer_part.cpp17
-rw-r--r--korganizer/korganizer_part.h6
-rw-r--r--korganizer/korganizeriface.h10
-rw-r--r--korganizer/korganizerifaceimpl.cpp13
-rw-r--r--korganizer/korganizerifaceimpl.h5
-rw-r--r--korganizer/kotimelineview.cpp25
-rw-r--r--korganizer/kotimelineview.h4
-rw-r--r--korganizer/kotodoeditor.cpp113
-rw-r--r--korganizer/kotodoeditor.h9
-rw-r--r--korganizer/kotodoview.cpp148
-rw-r--r--korganizer/kotodoview.h12
-rw-r--r--korganizer/kotodoviewitem.cpp95
-rw-r--r--korganizer/koviewmanager.cpp204
-rw-r--r--korganizer/koviewmanager.h35
-rw-r--r--korganizer/kowhatsnextview.cpp11
-rw-r--r--korganizer/kowhatsnextview.h8
-rw-r--r--korganizer/multiagendaview.cpp271
-rw-r--r--korganizer/multiagendaview.h15
-rw-r--r--korganizer/navigatorbar.cpp114
-rw-r--r--korganizer/navigatorbar.h15
-rw-r--r--korganizer/plugins/datenums/datenums.desktop2
-rw-r--r--korganizer/plugins/exchange/exchange.desktop2
-rw-r--r--korganizer/plugins/hebrew/hebrew.cpp8
-rw-r--r--korganizer/plugins/hebrew/hebrew.desktop2
-rw-r--r--korganizer/plugins/printing/journal/journalprint.cpp8
-rw-r--r--korganizer/plugins/printing/journal/journalprint.desktop2
-rw-r--r--korganizer/plugins/printing/list/listprint.desktop2
-rw-r--r--korganizer/plugins/printing/whatsnext/whatsnextprint.desktop4
-rw-r--r--korganizer/plugins/printing/year/yearprint.cpp9
-rw-r--r--korganizer/plugins/printing/year/yearprint.desktop2
-rw-r--r--korganizer/plugins/timespanview/timespanview.desktop2
-rw-r--r--korganizer/previewdialog.cpp163
-rw-r--r--korganizer/previewdialog.h69
-rw-r--r--korganizer/printing/calprintdefaultplugins.cpp372
-rw-r--r--korganizer/printing/calprintdefaultplugins.h136
-rw-r--r--korganizer/printing/calprintpluginbase.cpp276
-rw-r--r--korganizer/printing/calprintpluginbase.h70
-rw-r--r--korganizer/publishdialog.cpp3
-rw-r--r--korganizer/resourceview.cpp391
-rw-r--r--korganizer/resourceview.h61
-rw-r--r--korganizer/searchdialog.cpp16
-rw-r--r--korganizer/searchdialog.h6
-rw-r--r--korganizer/timelabels.cpp12
-rw-r--r--korganizer/timelineitem.cpp12
-rw-r--r--korganizer/timelineitem.h5
-rw-r--r--korganizer/tips2
-rw-r--r--korganizer/urihandler.cpp70
-rw-r--r--korganizer/urihandler.h9
-rw-r--r--korganizer/version.h2
172 files changed, 8785 insertions, 3713 deletions
diff --git a/korganizer/Makefile.am b/korganizer/Makefile.am
index 8b6e4d91..6b434ab8 100644
--- a/korganizer/Makefile.am
+++ b/korganizer/Makefile.am
@@ -90,7 +90,7 @@ libkorganizer_la_SOURCES = komessagebox.cpp \
koeventview.cpp \
korganizeriface.skel kcalendariface.skel \
filtereditdialog.cpp filteredit_base.ui \
- kowhatsnextview.cpp kocounterdialog.cpp \
+ kowhatsnextview.cpp \
kojournalview.cpp journalentry.cpp \
kocore.cpp mailscheduler.cpp \
kodaymatrix.cpp docprefs.cpp statusdialog.cpp\
@@ -101,6 +101,7 @@ libkorganizer_la_SOURCES = komessagebox.cpp \
koprefs_base.kcfgc \
koincidencetooltip.cpp aboutdata.cpp \
importdialog.cpp \
+ previewdialog.cpp \
korganizerifaceimpl.cpp \
freebusymanager.cpp freebusyurldialog.cpp \
eventarchiver.cpp koidentitymanager.cpp \
@@ -174,10 +175,10 @@ KDE_ICON = AUTO
META_INCLUDES = $(srcdir)/interfaces/korganizer
messages: rc.cpp
- $(PREPARETIPS) > tips.txt
+ $(PREPARETIPS) > tips.cpp
$(EXTRACTRC) `find . -name "*.rc" -o -name "*.ui" -o -name "*.kcfg"` >> rc.cpp
- $(XGETTEXT) `find . -name "*.cpp" -o -name "*.h" -o -name "*.txt"` -o $(podir)/korganizer.pot
- rm -f tips.txt
+ $(XGETTEXT) `find . -name "*.cpp" -o -name "*.h"` -o $(podir)/korganizer.pot
+ rm -f tips.cpp
xdg_apps_DATA = korganizer.desktop
diff --git a/korganizer/Todo-info.text b/korganizer/Todo-info.text
new file mode 100644
index 00000000..19d91116
--- /dev/null
+++ b/korganizer/Todo-info.text
@@ -0,0 +1,18 @@
+
+ TODO's behavior in agenda and month views
+
+
+Here are the rules for how/when/where should to-dos be displayed in agenda/month view:
+
+* startDt doesn't influence to-do behavior, it's irrelevant
+* To-dos without dueDt aren't shown
+* The time component doesn't influence the behavior in month view, only agenda
+* Overdue to-dos appear today, and not at dtDue, so we don't forget them
+* In agenda, if the to-do is overdue and has time, it should appear in the all
+ day area because, since it's overdue, you must do it ASAP and not wait for the
+ original time.
+
+* In agenda, a not-overdue to-do, with time, is drawn with the rectangle ending
+ at dtDue, and not starting at dtDue. If dtDue is at 00h00, then it should be
+ displayed in the previous day, ending at 23:59:59
+
diff --git a/korganizer/aboutdata.cpp b/korganizer/aboutdata.cpp
index f372d11f..b5fb98c3 100644
--- a/korganizer/aboutdata.cpp
+++ b/korganizer/aboutdata.cpp
@@ -34,10 +34,11 @@ AboutData::AboutData()
KAboutData::License_GPL,
"(c) 1997-1999 Preston Brown\n"
"(c) 2000-2004 Cornelius Schumacher\n"
- "(c) 2004-2005 Reinhold Kainhofer", 0,
+ "(c) 2004-2005 Reinhold Kainhofer\n"
+ "(c) 2009-2010 Timothy Pearson", 0,
"http://korganizer.kde.org" )
{
- addAuthor("Timothy Pearson",I18N_NOOP("Current Maintainer"),
+ addAuthor("Timothy Pearson",I18N_NOOP("Current Developer/Maintainer"),
"kb9vqf@pearsoncomputing.net");
addAuthor("Reinhold Kainhofer",I18N_NOOP("Previous maintainer"),
"reinhold@kainhofer.com");
diff --git a/korganizer/actionmanager.cpp b/korganizer/actionmanager.cpp
index 99939ef1..b9df9e86 100644
--- a/korganizer/actionmanager.cpp
+++ b/korganizer/actionmanager.cpp
@@ -26,7 +26,7 @@
*/
#include "actionmanager.h"
-
+#include "previewdialog.h"
#include "alarmclient.h"
#include "calendarview.h"
#include "kocore.h"
@@ -34,13 +34,15 @@
#include "koglobals.h"
#include "koprefs.h"
#include "koviewmanager.h"
+#include "koagendaview.h"
+#include "multiagendaview.h"
#include "kowindowlist.h"
#include "kprocess.h"
#include "konewstuff.h"
#include "history.h"
#include "kogroupware.h"
#include "resourceview.h"
-#include "importdialog.h"
+#include "previewdialog.h"
#include "eventarchiver.h"
#include "stdcalendar.h"
#include "freebusymanager.h"
@@ -68,13 +70,13 @@
#include <kstdguiitem.h>
#include <kdeversion.h>
#include <kactionclasses.h>
+#include <kcmdlineargs.h>
#include <tqapplication.h>
#include <tqcursor.h>
#include <tqtimer.h>
#include <tqlabel.h>
-
// FIXME: Several places in the file don't use KConfigXT yet!
KOWindowList *ActionManager::mWindowList = 0;
@@ -153,12 +155,12 @@ void ActionManager::init()
connect( mCalendarView, TQT_SIGNAL( modifiedChanged( bool ) ), TQT_SLOT( setTitle() ) );
connect( mCalendarView, TQT_SIGNAL( configChanged() ), TQT_SLOT( updateConfig() ) );
- connect( mCalendarView, TQT_SIGNAL( incidenceSelected( Incidence * ) ),
- this, TQT_SLOT( processIncidenceSelection( Incidence * ) ) );
+ connect( mCalendarView, TQT_SIGNAL( incidenceSelected( Incidence *,const TQDate & ) ),
+ this, TQT_SLOT( processIncidenceSelection( Incidence *,const TQDate & ) ) );
connect( mCalendarView, TQT_SIGNAL( exportHTML( HTMLExportSettings * ) ),
this, TQT_SLOT( exportHTML( HTMLExportSettings * ) ) );
- processIncidenceSelection( 0 );
+ processIncidenceSelection( 0, TQDate() );
// Update state of paste action
mCalendarView->checkClipboard();
@@ -197,7 +199,7 @@ void ActionManager::createCalendarResources()
mResourceView = factory.resourceView();
connect( mCalendarResources, TQT_SIGNAL( calendarChanged() ),
- mCalendarView, TQT_SLOT(resourcesChanged() ) );
+ mCalendarView, TQT_SLOT( resourcesChanged() ) );
connect( mCalendarResources, TQT_SIGNAL( signalErrorMessage( const TQString & ) ),
mCalendarView, TQT_SLOT( showErrorMessage( const TQString & ) ) );
@@ -250,9 +252,9 @@ void ActionManager::initActions()
//~~~~~~~~~~~~~~~~~~~~~~~~ IMPORT / EXPORT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- new KAction( i18n("Import &Calendar..."), 0, this, TQT_SLOT( file_merge() ),
+ new KAction( i18n("Import &Event/Calendar (ICS-/VCS-File)..."), 0, this, TQT_SLOT( file_merge() ),
mACollection, "import_icalendar" );
- new KAction( i18n("&Import From UNIX Ical tool"), 0, this, TQT_SLOT( file_icalimport() ),
+ new KAction( i18n("&Import From UNIX Ical tool (.calendar-File)"), 0, this, TQT_SLOT( file_icalimport() ),
mACollection, "import_ical" );
new KAction( i18n("Get &Hot New Stuff..."), 0, this,
TQT_SLOT( downloadNewStuff() ), mACollection,
@@ -312,10 +314,10 @@ void ActionManager::initActions()
mACollection, "edit_delete" );
if ( mIsPart ) {
KStdAction::find( mCalendarView->dialogManager(), TQT_SLOT( showSearchDialog() ),
- mACollection, "korganizer_find" );
+ mACollection, "korganizer_find" );
} else {
KStdAction::find( mCalendarView->dialogManager(), TQT_SLOT( showSearchDialog() ),
- mACollection );
+ mACollection );
}
pasteAction->setEnabled( false );
mUndoAction->setEnabled( false );
@@ -447,11 +449,11 @@ void ActionManager::initActions()
//************************** Actions MENU *********************************
new KAction( i18n("New E&vent..."),
KOGlobals::self()->smallIcon( "newappointment" ), 0,
- mCalendarView, TQT_SLOT( newEvent() ),
+ mCalendarView, TQT_SLOT(newEvent()),
mACollection, "new_event" );
new KAction( i18n("New &To-do..."),
KOGlobals::self()->smallIcon( "newtodo" ), 0,
- mCalendarView, TQT_SLOT( newTodo() ),
+ mCalendarView, TQT_SLOT(newTodo()),
mACollection, "new_todo" );
action = new KAction( i18n("New Su&b-to-do..."), 0,
mCalendarView,TQT_SLOT( newSubTodo() ),
@@ -461,7 +463,7 @@ void ActionManager::initActions()
action,TQT_SLOT( setEnabled( bool ) ) );
new KAction( i18n("New &Journal..."),
KOGlobals::self()->smallIcon( "newjournal" ), 0,
- mCalendarView, TQT_SLOT( newJournal() ),
+ mCalendarView, TQT_SLOT(newJournal()),
mACollection, "new_journal" );
mShowIncidenceAction = new KAction( i18n("&Show"), 0,
@@ -498,40 +500,42 @@ void ActionManager::initActions()
mACollection, "schedule_publish" );
mPublishEvent->setEnabled( false );
- action = new KAction( i18n("Send &Invitation to Attendees"),"mail_generic",0,
- mCalendarView,TQT_SLOT( schedule_request() ),
- mACollection,"schedule_request" );
- action->setEnabled( false );
- connect( mCalendarView, TQT_SIGNAL( organizerEventsSelected( bool ) ),
- action, TQT_SLOT( setEnabled( bool ) ) );
-
- action = new KAction( i18n("Re&quest Update"), 0,
- mCalendarView, TQT_SLOT( schedule_refresh() ),
- mACollection, "schedule_refresh" );
- action->setEnabled( false );
- connect( mCalendarView,TQT_SIGNAL( groupEventsSelected( bool ) ),
- action,TQT_SLOT( setEnabled( bool ) ) );
-
- action = new KAction( i18n("Send &Cancelation to Attendees"), 0,
- mCalendarView, TQT_SLOT( schedule_cancel() ),
- mACollection, "schedule_cancel" );
- action->setEnabled( false );
- connect( mCalendarView,TQT_SIGNAL( organizerEventsSelected( bool ) ),
- action,TQT_SLOT( setEnabled( bool ) ) );
-
- action = new KAction( i18n("Send Status &Update"),"mail_reply",0,
- mCalendarView,TQT_SLOT( schedule_reply() ),
- mACollection,"schedule_reply" );
- action->setEnabled( false );
- connect( mCalendarView,TQT_SIGNAL( groupEventsSelected( bool ) ),
- action,TQT_SLOT( setEnabled( bool ) ) );
-
- action = new KAction( i18n("counter proposal","Request Chan&ge"),0,
- mCalendarView,TQT_SLOT( schedule_counter() ),
- mACollection, "schedule_counter" );
- action->setEnabled( false );
- connect( mCalendarView,TQT_SIGNAL( groupEventsSelected( bool ) ),
- action,TQT_SLOT( setEnabled( bool ) ) );
+ mSendInvitation = new KAction( i18n( "Send &Invitation to Attendees" ),
+ "mail_generic", 0,
+ mCalendarView, TQT_SLOT(schedule_request()),
+ mACollection, "schedule_request" );
+ mSendInvitation->setEnabled( false );
+ connect( mCalendarView, TQT_SIGNAL(organizerEventsSelected(bool)),
+ mSendInvitation, TQT_SLOT(setEnabled(bool)) );
+
+ mRequestUpdate = new KAction( i18n( "Re&quest Update" ), 0,
+ mCalendarView, TQT_SLOT(schedule_refresh()),
+ mACollection, "schedule_refresh" );
+ mRequestUpdate->setEnabled( false );
+ connect( mCalendarView, TQT_SIGNAL(groupEventsSelected(bool)),
+ mRequestUpdate, TQT_SLOT(setEnabled(bool)) );
+
+ mSendCancel = new KAction( i18n( "Send &Cancelation to Attendees" ), 0,
+ mCalendarView, TQT_SLOT(schedule_cancel()),
+ mACollection, "schedule_cancel" );
+ mSendCancel->setEnabled( false );
+ connect( mCalendarView, TQT_SIGNAL(organizerEventsSelected(bool)),
+ mSendCancel, TQT_SLOT(setEnabled(bool)) );
+
+ mSendStatusUpdate = new KAction( i18n( "Send Status &Update" ),
+ "mail_reply", 0,
+ mCalendarView,TQT_SLOT(schedule_reply()),
+ mACollection, "schedule_reply" );
+ mSendStatusUpdate->setEnabled( false );
+ connect( mCalendarView, TQT_SIGNAL(groupEventsSelected(bool)),
+ mSendStatusUpdate, TQT_SLOT(setEnabled(bool)) );
+
+ mRequestChange = new KAction( i18n( "counter proposal", "Request Chan&ge" ), 0,
+ mCalendarView, TQT_SLOT(schedule_counter()),
+ mACollection, "schedule_counter" );
+ mRequestChange->setEnabled( false );
+ connect( mCalendarView, TQT_SIGNAL(groupEventsSelected(bool)),
+ mRequestChange, TQT_SLOT(setEnabled(bool)) );
mForwardEvent = new KAction( i18n("&Send as iCalendar..."), "mail_forward", 0,
mCalendarView, TQT_SLOT(schedule_forward()),
@@ -719,7 +723,7 @@ void ActionManager::file_open( const KURL &url )
// is that URL already opened somewhere else? Activate that window
KOrg::MainWindow *korg=ActionManager::findInstance( url );
if ( ( 0 != korg )&&( korg != mMainWindow ) ) {
- KWin::setActiveWindow( korg->topLevelWidget()->winId() );
+ KWin::activateWindow( korg->topLevelWidget()->winId() );
return;
}
@@ -745,7 +749,7 @@ void ActionManager::file_icalimport()
if ( !TQFile::exists( homeDir ) ) {
KMessageBox::error( dialogParent(),
- i18n( "You have no ical file in your home directory.\n"
+ i18n( "You have no .calendar file in your home directory.\n"
"Import cannot proceed.\n" ) );
return;
}
@@ -1055,6 +1059,11 @@ void ActionManager::exportHTML( HTMLExportSettings *settings )
{
if ( !settings || settings->outputFile().isEmpty() )
return;
+ kdDebug()<<" settings->outputFile() :"<<settings->outputFile()<<endl;
+ if ( TQFileInfo( settings->outputFile() ).exists() ) {
+ if(KMessageBox::questionYesNo( dialogParent(), i18n("Do you want to overwrite file \"%1\"").arg( settings->outputFile()) ) == KMessageBox::No)
+ return;
+ }
settings->setEMail( KOPrefs::instance()->email() );
settings->setName( KOPrefs::instance()->fullName() );
@@ -1376,11 +1385,16 @@ TQString ActionManager::getCurrentURLasString() const
return mURL.url();
}
-bool ActionManager::editIncidence( const TQString& uid )
+bool ActionManager::editIncidence( const TQString &uid )
{
return mCalendarView->editIncidence( uid );
}
+bool ActionManager::editIncidence( const TQString &uid, const TQDate &date )
+{
+ return mCalendarView->editIncidence( uid, date );
+}
+
bool ActionManager::deleteIncidence( const TQString& uid, bool force )
{
return mCalendarView->deleteIncidence( uid, force );
@@ -1454,7 +1468,7 @@ class ActionManager::ActionStringsVisitor : public IncidenceBase::Visitor
KAction *mDelete;
};
-void ActionManager::processIncidenceSelection( Incidence *incidence )
+void ActionManager::processIncidenceSelection( Incidence *incidence, const TQDate & )
{
// kdDebug(5850) << "ActionManager::processIncidenceSelection()" << endl;
@@ -1490,6 +1504,11 @@ void ActionManager::enableIncidenceActions( bool enabled )
mDeleteAction->setEnabled( enabled );
mPublishEvent->setEnabled( enabled );
mForwardEvent->setEnabled( enabled );
+ mSendInvitation->setEnabled( enabled );
+ mSendCancel->setEnabled( enabled );
+ mSendStatusUpdate->setEnabled( enabled );
+ mRequestChange->setEnabled( enabled );
+ mRequestUpdate->setEnabled( enabled );
}
void ActionManager::keyBindings()
@@ -1525,16 +1544,108 @@ KCalendarIface::ResourceRequestReply ActionManager::resourceRequest( const TQVal
return reply;
}
+QPair<ResourceCalendar *, TQString> ActionManager::viewSubResourceCalendar()
+{
+ QPair<ResourceCalendar *, TQString> p( 0, TQString() );
+
+ // return now if we are running as a part and we aren't the currently active part
+ if ( mIsPart && !mMainWindow->isCurrentlyActivePart() ) {
+ return p;
+ }
+
+ KOrg::BaseView *cV = mCalendarView->viewManager()->currentView();
+ if ( cV && cV == mCalendarView->viewManager()->multiAgendaView() ) {
+ cV = mCalendarView->viewManager()->multiAgendaView()->selectedAgendaView();
+ }
+ if ( cV ) {
+ p = qMakePair( cV->resourceCalendar(), cV->subResourceCalendar() );
+ }
+ return p;
+}
+
+bool ActionManager::isWritable( ResourceCalendar *res, const TQString &subRes,
+ const TQString &contentsType )
+{
+
+ if ( res && res->isActive() ) {
+ // Check specified resource for writability.
+ if ( res->readOnly() || !res->subresourceWritable( subRes ) ) {
+ TQString resName = res->resourceName();
+ if ( res->canHaveSubresources() ) {
+ resName = res->labelForSubresource( subRes );
+ }
+ KMessageBox::sorry(
+ dialogParent(),
+ i18n( "\"%1\" is read-only. "
+ "Please select a writable calendar before attempting to create a new item." ).
+ arg( resName ),
+ i18n( "Read-only calendar" ) );
+ return false;
+ } else {
+ return true;
+ }
+ } else {
+ // No specific resource so let's check all possible calendars for writability.
+ CalendarResourceManager *m = mCalendarResources->resourceManager();
+ CalendarResourceManager::ActiveIterator it;
+ for ( it = m->activeBegin(); it != m->activeEnd(); ++it ) {
+ ResourceCalendar *res = (*it);
+ if ( res->canHaveSubresources() ) {
+ TQStringList subResources = res->subresources();
+ for ( TQStringList::ConstIterator subit = subResources.constBegin();
+ subit != subResources.constEnd(); ++subit ) {
+ if ( res->subresourceWritable( (*subit) ) && res->subresourceActive( (*subit) ) ) {
+ if ( res->subresourceType( *subit ).isEmpty() ||
+ res->subresourceType( *subit ) == contentsType ) {
+ return true;
+ }
+ }
+ }
+ } else if ( !res->readOnly() ) {
+ return true;
+ }
+ }
+ // we don't have any writable calendars
+ TQString errorText;
+ if ( contentsType == "event" ) {
+ errorText =
+ i18n( "You have no active, writable event folder so saving will not be possible.\n"
+ "Please create or activate at least one writable event folder and try again." );
+ } else if ( contentsType == "todo" ) {
+ errorText =
+ i18n( "You have no active, writable to-do (task) folders so saving will not be possible.\n"
+ "Please create or activate at least one writable to-do folder and try again." );
+ } else if ( contentsType == "journal" ) {
+ errorText =
+ i18n( "You have no active, writable journal folder so saving will not be possible.\n"
+ "Please create or activate at least one writable journal folder and try again." );
+ } else {
+ errorText =
+ i18n( "You have no active, writable calendar folder so saving will not be possible.\n"
+ "Please create or activate at least one writable calendar folder and try again." );
+ }
+ KMessageBox::sorry(
+ dialogParent(),
+ errorText,
+ i18n( "No writable calendar" ) );
+ return false;
+ }
+}
+
void ActionManager::openEventEditor( const TQString& text )
{
- mCalendarView->newEvent( text );
+ QPair<ResourceCalendar *, TQString>p = viewSubResourceCalendar();
+ if ( isWritable( p.first, p.second, "event" ) ) {
+ mCalendarView->newEvent( p.first, p.second, text );
+ }
}
void ActionManager::openEventEditor( const TQString& summary,
const TQString& description,
const TQString& attachment )
{
- mCalendarView->newEvent( summary, description, attachment );
+ QPair<ResourceCalendar *, TQString>p = viewSubResourceCalendar();
+ mCalendarView->newEvent( p.first, p.second, summary, description, attachment );
}
void ActionManager::openEventEditor( const TQString& summary,
@@ -1542,7 +1653,7 @@ void ActionManager::openEventEditor( const TQString& summary,
const TQString& attachment,
const TQStringList& attendees )
{
- mCalendarView->newEvent( summary, description, attachment, attendees );
+ mCalendarView->newEvent( 0, TQString(), summary, description, attachment, attendees );
}
void ActionManager::openEventEditor( const TQString & summary,
@@ -1637,19 +1748,25 @@ void ActionManager::openEventEditor( const TQString & summary,
return;
}
- mCalendarView->newEvent( summary, description, attData, attendees, attachmentMimetype, action != KOPrefs::Link );
+ QPair<ResourceCalendar *, TQString>p = viewSubResourceCalendar();
+ mCalendarView->newEvent( p.first, p.second, summary, description, attData,
+ attendees, attachmentMimetype, action != KOPrefs::Link );
}
void ActionManager::openTodoEditor( const TQString& text )
{
- mCalendarView->newTodo( text );
+ QPair<ResourceCalendar *, TQString>p = viewSubResourceCalendar();
+ if ( isWritable( p.first, p.second, "todo" ) ) {
+ mCalendarView->newTodo( p.first, p.second, text );
+ }
}
void ActionManager::openTodoEditor( const TQString& summary,
const TQString& description,
const TQString& attachment )
{
- mCalendarView->newTodo( summary, description, attachment );
+ QPair<ResourceCalendar *, TQString>p = viewSubResourceCalendar();
+ mCalendarView->newTodo( p.first, p.second, summary, description, attachment );
}
void ActionManager::openTodoEditor( const TQString& summary,
@@ -1657,7 +1774,8 @@ void ActionManager::openTodoEditor( const TQString& summary,
const TQString& attachment,
const TQStringList& attendees )
{
- mCalendarView->newTodo( summary, description, attachment, attendees );
+ QPair<ResourceCalendar *, TQString>p = viewSubResourceCalendar();
+ mCalendarView->newTodo( p.first, p.second, summary, description, attachment, attendees );
}
void ActionManager::openTodoEditor(const TQString & summary,
@@ -1665,7 +1783,8 @@ void ActionManager::openTodoEditor(const TQString & summary,
const TQString & uri,
const TQString & file,
const TQStringList & attendees,
- const TQString & attachmentMimetype)
+ const TQString & attachmentMimetype,
+ bool isTask )
{
int action = KOPrefs::instance()->defaultTodoAttachMethod();
if ( attachmentMimetype != "message/rfc822" ) {
@@ -1680,37 +1799,48 @@ void ActionManager::openTodoEditor(const TQString & summary,
delete menu;
}
- TQString attData;
+ TQStringList attData;
switch ( action ) {
case KOPrefs::TodoAttachAsk:
return;
case KOPrefs::TodoAttachLink:
- attData = uri;
+ attData << uri;
break;
- case KOPrefs::TodoAttachInlineFull:
- attData = file;
+ case KOPrefs::TodoAttachInlineFull:
+ attData << file;
break;
default:
// menu could have been closed by cancel, if so, do nothing
return;
}
- mCalendarView->newTodo( summary, description, attData, attendees, attachmentMimetype, action != KOPrefs::Link );
+ QPair<ResourceCalendar *, TQString>p = viewSubResourceCalendar();
+ mCalendarView->newTodo( p.first, p.second,
+ summary, description,
+ attData, attendees,
+ TQStringList( attachmentMimetype ),
+ action != KOPrefs::TodoAttachLink,
+ isTask );
}
void ActionManager::openJournalEditor( const TQDate& date )
{
- mCalendarView->newJournal( date );
+ QPair<ResourceCalendar *, TQString>p = viewSubResourceCalendar();
+ mCalendarView->newJournal( p.first, p.second, date );
}
void ActionManager::openJournalEditor( const TQString& text, const TQDate& date )
{
- mCalendarView->newJournal( text, date );
+ QPair<ResourceCalendar *, TQString>p = viewSubResourceCalendar();
+ mCalendarView->newJournal( p.first, p.second, text, date );
}
void ActionManager::openJournalEditor( const TQString& text )
{
- mCalendarView->newJournal( text );
+ QPair<ResourceCalendar *, TQString>p = viewSubResourceCalendar();
+ if ( isWritable( p.first, p.second, "journal" ) ) {
+ mCalendarView->newJournal( p.first, p.second, text );
+ }
}
//TODO:
@@ -1718,7 +1848,8 @@ void ActionManager::openJournalEditor( const TQString& text )
// const TQString& description,
// const TQString& attachment )
// {
-// mCalendarView->newJournal( summary, description, attachment );
+// QPair<ResourceCalendar *, TQString>p = viewSubResourceCalendar();
+// mCalendarView->newJournal( p.first, p.second, summary, description, attachment );
// }
@@ -1879,21 +2010,23 @@ void ActionManager::importCalendar( const KURL &url )
return;
}
- ImportDialog *dialog;
- dialog = new ImportDialog( url, mMainWindow->topLevelWidget() );
- connect( dialog, TQT_SIGNAL( dialogFinished( ImportDialog * ) ),
- TQT_SLOT( slotImportDialogFinished( ImportDialog * ) ) );
+ PreviewDialog *dialog;
+ dialog = new PreviewDialog( url, mMainWindow->topLevelWidget() );
+ connect( dialog, TQT_SIGNAL( dialogFinished( PreviewDialog * ) ),
+ TQT_SLOT( slotPreviewDialogFinished( PreviewDialog * ) ) );
connect( dialog, TQT_SIGNAL( openURL( const KURL &, bool ) ),
TQT_SLOT( openURL( const KURL &, bool ) ) );
- connect( dialog, TQT_SIGNAL( newWindow( const KURL & ) ),
- TQT_SIGNAL( actionNew( const KURL & ) ) );
connect( dialog, TQT_SIGNAL( addResource( const KURL & ) ),
TQT_SLOT( addResource( const KURL & ) ) );
- dialog->show();
+ if ( dialog->loadCalendar() ) {
+ dialog->show();
+ } else {
+ KMessageBox::error( dialogParent(), i18n("Unable to open the calendar") );
+ }
}
-void ActionManager::slotImportDialogFinished( ImportDialog *dlg )
+void ActionManager::slotPreviewDialogFinished( PreviewDialog *dlg )
{
dlg->deleteLater();
mCalendarView->updateView();
@@ -1959,6 +2092,42 @@ void ActionManager::saveToProfile( const TQString & path ) const
::copyConfigEntry( cfg, &profile, "Views", "Agenda View Calendar Display" );
}
+bool ActionManager::handleCommandLine()
+{
+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
+ KOrg::MainWindow *mainWindow = ActionManager::findInstance( KURL() );
+
+ bool ret = true;
+
+ if ( !mainWindow ) {
+ kdError() << "Unable to find default calendar resources view." << endl;
+ ret = false;
+ } else if ( args->count() <= 0 ) {
+ // No filenames given => all other args are meaningless, show main Window
+ mainWindow->topLevelWidget()->show();
+ } else if ( !args->isSet( "open" ) ) {
+ // Import, merge, or ask => we need the resource calendar window anyway.
+ mainWindow->topLevelWidget()->show();
+
+ // Check for import, merge or ask
+ if ( args->isSet( "import" ) ) {
+ for( int i = 0; i < args->count(); ++i ) {
+ mainWindow->actionManager()->addResource( args->url( i ) );
+ }
+ } else if ( args->isSet( "merge" ) ) {
+ for( int i = 0; i < args->count(); ++i ) {
+ mainWindow->actionManager()->mergeURL( args->url( i ).url() );
+ }
+ } else {
+ for( int i = 0; i < args->count(); ++i ) {
+ mainWindow->actionManager()->importCalendar( args->url( i ) );
+ }
+ }
+ }
+
+ return ret;
+}
+
TQWidget *ActionManager::dialogParent()
{
return mCalendarView->topLevelWidget();
diff --git a/korganizer/actionmanager.h b/korganizer/actionmanager.h
index 25fd6fab..555d4e7d 100644
--- a/korganizer/actionmanager.h
+++ b/korganizer/actionmanager.h
@@ -41,8 +41,7 @@ namespace KCal
class Incidence;
class ResourceCalendar;
}
-namespace KOrg
-{
+namespace KOrg {
class MainWindow;
}
@@ -59,7 +58,7 @@ class CalendarView;
class KOrganizer;
class KONewStuff;
class KOWindowList;
-class ImportDialog;
+class PreviewDialog;
class ResourceView;
class HTMLExportSettings;
@@ -152,7 +151,8 @@ class KDE_EXPORT ActionManager : public TQObject, public KCalendarIface
*/
virtual bool deleteIncidence( const TQString& uid, bool force = false );
- bool editIncidence( const TQString& uid );
+ bool editIncidence( const TQString &uid );
+ bool editIncidence( const TQString &uid, const TQDate &date );
/**
Add an incidence to the active calendar.
@@ -194,7 +194,8 @@ class KDE_EXPORT ActionManager : public TQObject, public KCalendarIface
const TQString& uri,
const TQString& file,
const TQStringList& attendees,
- const TQString& attachmentMimetype );
+ const TQString& attachmentMimetype,
+ bool isTask );
void openJournalEditor( const TQDate& date );
void openJournalEditor( const TQString& text, const TQDate& date );
@@ -220,6 +221,8 @@ class KDE_EXPORT ActionManager : public TQObject, public KCalendarIface
void saveToProfile( const TQString & path ) const;
+ bool handleCommandLine();
+
signals:
/**
Emitted when the "New" action is activated.
@@ -251,7 +254,7 @@ class KDE_EXPORT ActionManager : public TQObject, public KCalendarIface
void setDestinationPolicy();
- void processIncidenceSelection( Incidence * );
+ void processIncidenceSelection( Incidence *incidence, const TQDate &date );
void keyBindings();
/**
@@ -342,7 +345,7 @@ class KDE_EXPORT ActionManager : public TQObject, public KCalendarIface
void updateRedoAction( const TQString & );
- void slotImportDialogFinished( ImportDialog * );
+ void slotPreviewDialogFinished( PreviewDialog * );
protected:
/** Get URL for saving. Opens FileDialog. */
@@ -367,6 +370,9 @@ class KDE_EXPORT ActionManager : public TQObject, public KCalendarIface
void initActions();
void enableIncidenceActions( bool enable );
+ QPair<ResourceCalendar *, TQString> viewSubResourceCalendar();
+ bool isWritable( ResourceCalendar *res, const TQString &subRes, const TQString &contentsType );
+
KOrg::Part::List mParts; // List of parts loaded
KURL mURL; // URL of calendar file
TQString mFile; // Local name of calendar file
@@ -401,6 +407,13 @@ class KDE_EXPORT ActionManager : public TQObject, public KCalendarIface
KAction *mPublishEvent;
KAction *mForwardEvent;
+ KAction *mSendInvitation;
+ KAction *mSendCancel;
+ KAction *mSendStatusUpdate;
+
+ KAction *mRequestChange;
+ KAction *mRequestUpdate;
+
KAction *mUndoAction;
KAction *mRedoAction;
diff --git a/korganizer/archivedialog.cpp b/korganizer/archivedialog.cpp
index 88d20fde..48c299e0 100644
--- a/korganizer/archivedialog.cpp
+++ b/korganizer/archivedialog.cpp
@@ -130,11 +130,11 @@ ArchiveDialog::ArchiveDialog(Calendar *cal,TQWidget *parent, const char *name)
l->setBuddy(mArchiveFile->lineEdit());
fileLayout->addWidget(mArchiveFile);
topLayout->addLayout(fileLayout);
-
- TQHGroupBox *typeBox = new TQHGroupBox( i18n("Type of Items to Archive"),
+
+ TQHGroupBox *typeBox = new TQHGroupBox( i18n("Type of Items to Archive"),
topFrame);
mEvents = new TQCheckBox( i18n("&Events"), typeBox );
- mTodos = new TQCheckBox( i18n("&To-dos"), typeBox );
+ mTodos = new TQCheckBox( i18n("Completed &To-dos"), typeBox );
topLayout->addWidget( typeBox );
TQWhatsThis::add( typeBox, i18n("Here you can select which items "
"should be archived. Events are archived if they "
diff --git a/korganizer/calendarview.cpp b/korganizer/calendarview.cpp
index eb294fe7..ba1bbe6e 100644
--- a/korganizer/calendarview.cpp
+++ b/korganizer/calendarview.cpp
@@ -65,6 +65,7 @@
#include "komailclient.h"
#include "multiagendaview.h"
+#include <libkcal/calhelper.h>
#include <libkcal/vcaldrag.h>
#include <libkcal/icaldrag.h>
#include <libkcal/icalformat.h>
@@ -130,7 +131,7 @@ CalendarView::CalendarView( TQWidget *parent, const char *name )
mExtensions.setAutoDelete( true );
- mNavigator = new DateNavigator( this );
+ mDateNavigator = new DateNavigator( this );
mDateChecker = new DateChecker( this );
TQBoxLayout *topLayout = new TQVBoxLayout( this );
@@ -145,14 +146,14 @@ CalendarView::CalendarView( TQWidget *parent, const char *name )
"CalendarView::LeftFrame" );
// mPanner->setResizeMode( mLeftSplitter, TQSplitter::Stretch );
- mDateNavigator = new DateNavigatorContainer( mLeftSplitter,
+ mDateNavigatorContainer = new DateNavigatorContainer( mLeftSplitter,
"CalendarView::DateNavigator" );
-// mLeftSplitter->setResizeMode( mDateNavigator, TQSplitter::Stretch );
- mLeftSplitter->setCollapsible( mDateNavigator, true );
+// mLeftSplitter->setResizeMode( mDateNavigatorContainer, TQSplitter::Stretch );
+ mLeftSplitter->setCollapsible( mDateNavigatorContainer, true );
mTodoList = new KOTodoView( CalendarNull::self(), mLeftSplitter, "todolist" );
- mEventViewer = new KOEventViewer( mLeftSplitter,"EventViewer" );
+ mEventViewer = new KOEventViewer( CalendarNull::self(), mLeftSplitter,"EventViewer" );
TQVBox *rightBox = new TQVBox( mPanner );
mNavigatorBar = new NavigatorBar( rightBox );
@@ -174,12 +175,12 @@ CalendarView::CalendarView( TQWidget *parent, const char *name )
topLayout->addWidget( mainBox );
- mDateNavigator = new KDateNavigator( leftFrame, true,
+ mDateNavigatorContainer = new KDateNavigator( leftFrame, true,
"CalendarView::DateNavigator",
TQDate::currentDate() );
mTodoList = new KOTodoView( CalendarNull::self(), leftFrame, "todolist" );
- mEventViewer = new KOEventViewer ( leftFrame, "EventViewer" );
+ mEventViewer = new KOEventViewer ( CalendarNull::self(), leftFrame, "EventViewer" );
TQWidget *rightBox = new TQWidget( mainBox );
TQBoxLayout *rightLayout = new TQVBoxLayout( rightBox );
@@ -193,55 +194,56 @@ CalendarView::CalendarView( TQWidget *parent, const char *name )
mLeftFrame = leftFrame;
if ( KOPrefs::instance()->mVerticalScreen ) {
-// mTodoList->setFixedHeight( 60 );
- mTodoList->setFixedHeight( mDateNavigator->sizeHint().height() );
+ // mTodoList->setFixedHeight( 60 );
+ mTodoList->setFixedHeight( mDateNavigatorContainer->sizeHint().height() );
}
#endif
- connect( mNavigator, TQT_SIGNAL( datesSelected( const KCal::DateList & ) ),
- TQT_SLOT( showDates( const KCal::DateList & ) ) );
- connect( mNavigator, TQT_SIGNAL( datesSelected( const KCal::DateList & ) ),
+ // Signals emited by mDateNavigator
+ connect( mDateNavigator, TQT_SIGNAL( datesSelected( const KCal::DateList &, const TQDate & ) ),
+ TQT_SLOT( showDates( const KCal::DateList &, const TQDate & ) ) );
+
+ // Signals emited by mNavigatorBar
+ connect( mNavigatorBar, TQT_SIGNAL( prevYearClicked() ),
+ mDateNavigator, TQT_SLOT( selectPreviousYear() ) );
+ connect( mNavigatorBar, TQT_SIGNAL( nextYearClicked() ),
+ mDateNavigator, TQT_SLOT( selectNextYear() ) );
+ connect( mNavigatorBar, TQT_SIGNAL( prevMonthClicked() ),
+ mDateNavigator, TQT_SLOT( selectPreviousMonth() ) );
+ connect( mNavigatorBar, TQT_SIGNAL( nextMonthClicked() ),
+ mDateNavigator, TQT_SLOT( selectNextMonth() ) );
+ connect( mNavigatorBar, TQT_SIGNAL( monthSelected(int) ),
+ mDateNavigator, TQT_SLOT( selectMonth(int) ) );
+ connect( mNavigatorBar, TQT_SIGNAL( yearSelected(int)),
+ mDateNavigator, TQT_SLOT(selectYear(int)) );
+
+
+ // Signals emited by mDateNavigatorContainer
+ connect( mDateNavigatorContainer, TQT_SIGNAL( weekClicked( const TQDate & ) ),
+ this, TQT_SLOT( selectWeek( const TQDate & ) ) );
+ connect( mDateNavigatorContainer, TQT_SIGNAL( prevMonthClicked(const TQDate &, const TQDate &, const TQDate &) ),
+ mDateNavigator, TQT_SLOT( selectPreviousMonth(const TQDate &, const TQDate &, const TQDate &) ) );
+ connect( mDateNavigatorContainer, TQT_SIGNAL( nextMonthClicked(const TQDate &, const TQDate &, const TQDate &) ),
+ mDateNavigator, TQT_SLOT( selectNextMonth(const TQDate &, const TQDate &, const TQDate &) ) );
+ connect( mDateNavigatorContainer, TQT_SIGNAL( prevYearClicked() ),
+ mDateNavigator, TQT_SLOT( selectPreviousYear() ) );
+ connect( mDateNavigatorContainer, TQT_SIGNAL( nextYearClicked() ),
+ mDateNavigator, TQT_SLOT( selectNextYear() ) );
+ connect( mDateNavigatorContainer, TQT_SIGNAL( monthSelected(int) ),
+ mDateNavigator, TQT_SLOT( selectMonth(int) ) );
+ connect( mDateNavigatorContainer, TQT_SIGNAL(yearSelected(int)),
+ mDateNavigator, TQT_SLOT(selectYear(int)) );
+ connect( mDateNavigatorContainer, TQT_SIGNAL( goPrevious() ),
+ mDateNavigator, TQT_SLOT( selectPrevious() ) );
+ connect( mDateNavigatorContainer, TQT_SIGNAL( goNext() ),
+ mDateNavigator, TQT_SLOT( selectNext() ) );
+
+ connect( mDateNavigatorContainer, TQT_SIGNAL( datesSelected( const KCal::DateList & ) ),
mDateNavigator, TQT_SLOT( selectDates( const KCal::DateList & ) ) );
- connect( mNavigatorBar, TQT_SIGNAL( goPrevYear() ),
- mNavigator, TQT_SLOT( selectPreviousYear() ) );
- connect( mNavigatorBar, TQT_SIGNAL( goNextYear() ),
- mNavigator, TQT_SLOT( selectNextYear() ) );
- connect( mNavigatorBar, TQT_SIGNAL( goPrevMonth() ),
- mNavigator, TQT_SLOT( selectPreviousMonth() ) );
- connect( mNavigatorBar, TQT_SIGNAL( goNextMonth() ),
- mNavigator, TQT_SLOT( selectNextMonth() ) );
- connect( mNavigatorBar, TQT_SIGNAL( goMonth(int) ),
- mNavigator, TQT_SLOT( selectMonth(int) ) );
-
- connect( mNavigator, TQT_SIGNAL( datesSelected( const KCal::DateList & ) ),
- mNavigatorBar, TQT_SLOT( selectDates( const KCal::DateList & ) ) );
-
- connect( mDateNavigator, TQT_SIGNAL( weekClicked( const TQDate & ) ),
- mNavigator, TQT_SLOT( selectWeek( const TQDate & ) ) );
-
- connect( mDateNavigator, TQT_SIGNAL( goPrevYear() ),
- mNavigator, TQT_SLOT( selectPreviousYear() ) );
- connect( mDateNavigator, TQT_SIGNAL( goNextYear() ),
- mNavigator, TQT_SLOT( selectNextYear() ) );
- connect( mDateNavigator, TQT_SIGNAL( goPrevMonth() ),
- mNavigator, TQT_SLOT( selectPreviousMonth() ) );
- connect( mDateNavigator, TQT_SIGNAL( goNextMonth() ),
- mNavigator, TQT_SLOT( selectNextMonth() ) );
- connect( mDateNavigator, TQT_SIGNAL( goMonth(int) ),
- mNavigator, TQT_SLOT( selectMonth(int) ) );
-
- connect( mDateNavigator, TQT_SIGNAL( goPrevious() ),
- mNavigator, TQT_SLOT( selectPrevious() ) );
- connect( mDateNavigator, TQT_SIGNAL( goNext() ),
- mNavigator, TQT_SLOT( selectNext() ) );
-
- connect( mDateNavigator, TQT_SIGNAL( datesSelected( const KCal::DateList & ) ),
- mNavigator, TQT_SLOT( selectDates( const KCal::DateList & ) ) );
-
- connect( mDateNavigator, TQT_SIGNAL(incidenceDropped(Incidence*, const TQDate&)),
+ connect( mDateNavigatorContainer, TQT_SIGNAL(incidenceDropped(Incidence*, const TQDate&)),
TQT_SLOT( addIncidenceOn( Incidence *, const TQDate & ) ) );
- connect( mDateNavigator, TQT_SIGNAL(incidenceDroppedMove(Incidence*,const TQDate&)),
+ connect( mDateNavigatorContainer, TQT_SIGNAL(incidenceDroppedMove(Incidence*,const TQDate&)),
TQT_SLOT( moveIncidenceTo( Incidence *, const TQDate & ) ) );
connect( mDateChecker, TQT_SIGNAL( dayPassed( const TQDate & ) ),
@@ -249,13 +251,13 @@ CalendarView::CalendarView( TQWidget *parent, const char *name )
connect( mDateChecker, TQT_SIGNAL( dayPassed( const TQDate & ) ),
TQT_SIGNAL( dayPassed( const TQDate & ) ) );
connect( mDateChecker, TQT_SIGNAL( dayPassed( const TQDate & ) ),
- mDateNavigator, TQT_SLOT( updateToday() ) );
+ mDateNavigatorContainer, TQT_SLOT( updateToday() ) );
connect( this, TQT_SIGNAL( configChanged() ),
- mDateNavigator, TQT_SLOT( updateConfig() ) );
+ mDateNavigatorContainer, TQT_SLOT( updateConfig() ) );
- connect( this, TQT_SIGNAL( incidenceSelected(Incidence *) ),
- mEventViewer, TQT_SLOT ( setIncidence (Incidence *) ) );
+ connect( this, TQT_SIGNAL( incidenceSelected(Incidence *, const TQDate &) ),
+ mEventViewer, TQT_SLOT ( setIncidence (Incidence *, const TQDate &) ) );
//TODO: do a pretty Summary,
TQString s;
@@ -267,7 +269,7 @@ CalendarView::CalendarView( TQWidget *parent, const char *name )
TQWhatsThis::add( mEventViewer,
i18n( "View the details of events, journal entries or to-dos "
"selected in KOrganizer's main view here." ) );
- mEventViewer->setIncidence( 0 );
+ mEventViewer->setIncidence( 0, TQDate() );
mViewManager->connectTodoView( mTodoList );
mViewManager->connectView( mTodoList );
@@ -278,10 +280,10 @@ CalendarView::CalendarView( TQWidget *parent, const char *name )
connect( TQApplication::clipboard(), TQT_SIGNAL( dataChanged() ),
TQT_SLOT( checkClipboard() ) );
- connect( mTodoList, TQT_SIGNAL( incidenceSelected( Incidence * ) ),
- TQT_SLOT( processTodoListSelection( Incidence * ) ) );
- disconnect( mTodoList, TQT_SIGNAL( incidenceSelected( Incidence * ) ),
- this, TQT_SLOT( processMainViewSelection( Incidence * ) ) );
+ connect( mTodoList, TQT_SIGNAL( incidenceSelected( Incidence *,const TQDate & ) ),
+ TQT_SLOT( processTodoListSelection( Incidence *,const TQDate & ) ) );
+ disconnect( mTodoList, TQT_SIGNAL( incidenceSelected( Incidence *,const TQDate & ) ),
+ this, TQT_SLOT( processMainViewSelection( Incidence *,const TQDate & ) ) );
kdDebug(5850) << "CalendarView::CalendarView() done" << endl;
}
@@ -313,9 +315,11 @@ void CalendarView::setCalendar( Calendar *cal )
mCalendar->registerObserver( this );
- mDateNavigator->setCalendar( mCalendar );
+ mDateNavigatorContainer->setCalendar( mCalendar );
mTodoList->setCalendar( mCalendar );
+
+ mEventViewer->setCalendar( mCalendar );
}
void CalendarView::setIncidenceChanger( IncidenceChangerBase *changer )
@@ -324,10 +328,8 @@ void CalendarView::setIncidenceChanger( IncidenceChangerBase *changer )
emit newIncidenceChanger( mChanger );
connect( mChanger, TQT_SIGNAL( incidenceAdded( Incidence* ) ),
this, TQT_SLOT( incidenceAdded( Incidence* ) ) );
- connect( mChanger, TQT_SIGNAL( incidenceChanged( Incidence*, Incidence*, int ) ),
- this, TQT_SLOT( incidenceChanged( Incidence*, Incidence*, int ) ) );
- connect( mChanger, TQT_SIGNAL( incidenceChanged( Incidence*, Incidence* ) ),
- this, TQT_SLOT( incidenceChanged( Incidence*, Incidence* ) ) );
+ connect( mChanger, TQT_SIGNAL( incidenceChanged( Incidence*, Incidence*, KOGlobals::WhatChanged ) ),
+ this, TQT_SLOT( incidenceChanged( Incidence*, Incidence*, KOGlobals::WhatChanged ) ) );
connect( mChanger, TQT_SIGNAL( incidenceToBeDeleted( Incidence * ) ),
this, TQT_SLOT( incidenceToBeDeleted( Incidence * ) ) );
connect( mChanger, TQT_SIGNAL( incidenceDeleted( Incidence * ) ),
@@ -347,6 +349,19 @@ Calendar *CalendarView::calendar()
else return CalendarNull::self();
}
+QPair<ResourceCalendar *, TQString> CalendarView::viewSubResourceCalendar()
+{
+ QPair<ResourceCalendar *, TQString> p( 0, TQString() );
+ KOrg::BaseView *cV = mViewManager->currentView();
+ if ( cV && cV == mViewManager->multiAgendaView() ) {
+ cV = mViewManager->multiAgendaView()->selectedAgendaView();
+ }
+ if ( cV ) {
+ p = qMakePair( cV->resourceCalendar(), cV->subResourceCalendar() );
+ }
+ return p;
+}
+
KOIncidenceEditor *CalendarView::editorDialog( Incidence *incidence ) const
{
if (mDialogList.find(incidence) != mDialogList.end ())
@@ -354,16 +369,53 @@ KOIncidenceEditor *CalendarView::editorDialog( Incidence *incidence ) const
else return 0;
}
+TQDate CalendarView::activeDate( bool fallbackToToday )
+{
+ KOrg::BaseView *curView = mViewManager->currentView();
+ if ( curView ) {
+ if ( curView->selectionStart().isValid() ) {
+ return curView->selectionStart().date();
+ }
+
+ // Try the view's selectedDates()
+ if ( !curView->selectedIncidenceDates().isEmpty() ) {
+ if ( curView->selectedIncidenceDates().first().isValid() ) {
+ return curView->selectedIncidenceDates().first();
+ }
+ }
+ }
+
+ // When all else fails, use the navigator start date, or today.
+ if ( fallbackToToday ) {
+ return TQDate::currentDate();
+ } else {
+ return mDateNavigator->selectedDates().first();
+ }
+}
+
+TQDate CalendarView::activeIncidenceDate()
+{
+ KOrg::BaseView *curView = mViewManager->currentView();
+ if ( curView ) {
+ DateList dates = curView->selectedIncidenceDates();
+ if ( !dates.isEmpty() ) {
+ return dates.first();
+ }
+ }
+
+ return TQDate();
+}
+
TQDate CalendarView::startDate()
{
- DateList dates = mNavigator->selectedDates();
+ DateList dates = mDateNavigator->selectedDates();
return dates.first();
}
TQDate CalendarView::endDate()
{
- DateList dates = mNavigator->selectedDates();
+ DateList dates = mDateNavigator->selectedDates();
return dates.last();
}
@@ -397,6 +449,23 @@ bool CalendarView::openCalendar(const TQString& filename, bool merge)
}
} else {
// merge in a file
+ CalendarResources *cl = dynamic_cast<CalendarResources *>( mCalendar );
+ if ( cl && !cl->hasCalendarResources() ) {
+ KMessageBox::sorry(
+ this,
+ i18n( "No calendars found, unable to merge the file into your calendar." ) );
+ return false;
+ }
+ // FIXME: This is a nasty hack, since we need to set a parent for the
+ // resource selection dialog. However, we don't have any UI methods
+ // in the calendar, only in the CalendarResources::DestinationPolicy
+ // So we need to type-cast it and extract it from the CalendarResources
+ TQWidget *tmpparent = 0;
+ if ( cl ) {
+ tmpparent = cl->dialogParentWidget();
+ cl->setDialogParentWidget( this );
+ }
+
FileStorage storage( mCalendar );
storage.setFileName( filename );
loadedSuccesfully = storage.load();
@@ -478,7 +547,7 @@ void CalendarView::readSettings()
TQValueList<int> sizes = config->readIntListEntry( "Separator1" );
if ( sizes.count() != 2 ) {
- sizes << mDateNavigator->minimumSizeHint().width();
+ sizes << mDateNavigatorContainer->minimumSizeHint().width();
sizes << 300;
}
mPanner->setSizes( sizes );
@@ -495,9 +564,12 @@ void CalendarView::readSettings()
readFilterSettings( config );
config->setGroup( "Views" );
- int dateCount = config->readNumEntry( "ShownDatesCount", 7 );
- if ( dateCount == 7 ) mNavigator->selectWeek();
- else mNavigator->selectDates( mNavigator->selectedDates().first(), dateCount );
+ const int dateCount = config->readNumEntry( "ShownDatesCount", 7 );
+ if ( dateCount == 7 ) {
+ mDateNavigator->selectWeek();
+ } else {
+ mDateNavigator->selectDates( mDateNavigator->selectedDates().first(), dateCount );
+ }
}
@@ -525,7 +597,7 @@ void CalendarView::writeSettings()
writeFilterSettings( config );
config->setGroup( "Views" );
- config->writeEntry( "ShownDatesCount", mNavigator->selectedDates().count() );
+ config->writeEntry( "ShownDatesCount", mDateNavigator->selectedDates().count() );
config->sync();
}
@@ -593,39 +665,42 @@ void CalendarView::writeFilterSettings( KConfig *config )
}
-void CalendarView::goDate( const TQDate& date )
+void CalendarView::goDate( const TQDate &date )
{
- mNavigator->selectDate( date );
+ mDateNavigator->selectDate( date );
}
-void CalendarView::showDate(const TQDate & date)
+void CalendarView::showDate( const TQDate &date )
{
- int dateCount = mNavigator->datesCount();
- if ( dateCount == 7 )
- mNavigator->selectWeek( date );
- else
- mNavigator->selectDates( date, dateCount );
+ int dateCount = mDateNavigator->datesCount();
+ if ( dateCount == 7 ) {
+ mDateNavigator->selectWeek( date );
+ } else {
+ mDateNavigator->selectDates( date, dateCount );
+ }
}
void CalendarView::goToday()
{
- mNavigator->selectToday();
+ mDateNavigator->selectToday();
}
void CalendarView::goNext()
{
- if ( dynamic_cast<KOMonthView*>( mViewManager->currentView() ) )
- mNavigator->selectNextMonth();
- else
- mNavigator->selectNext();
+ if ( dynamic_cast<KOMonthView*>( mViewManager->currentView() ) ) {
+ mDateNavigator->selectNextMonth();
+ } else {
+ mDateNavigator->selectNext();
+ }
}
void CalendarView::goPrevious()
{
- if ( dynamic_cast<KOMonthView*>( mViewManager->currentView() ) )
- mNavigator->selectPreviousMonth();
- else
- mNavigator->selectPrevious();
+ if ( dynamic_cast<KOMonthView*>( mViewManager->currentView() ) ) {
+ mDateNavigator->selectPreviousMonth();
+ } else {
+ mDateNavigator->selectPrevious();
+ }
}
void CalendarView::updateConfig( const TQCString& receiver)
@@ -660,16 +735,8 @@ void CalendarView::updateConfig( const TQCString& receiver)
}
emit configChanged();
- // force reload and handle agenda view type switch
- const bool showMerged = KOPrefs::instance()->agendaViewCalendarDisplay() == KOPrefs::CalendarsMerged;
- const bool showSideBySide = KOPrefs::instance()->agendaViewCalendarDisplay() == KOPrefs::CalendarsSideBySide;
- KOrg::BaseView *view = mViewManager->currentView();
- mViewManager->showAgendaView();
- if ( view == mViewManager->agendaView() && showSideBySide )
- view = mViewManager->multiAgendaView();
- else if ( view == mViewManager->multiAgendaView() && showMerged )
- view = mViewManager->agendaView();
- mViewManager->showView( view );
+ //switch beetween merged, side by side and tabbed agenda if needed
+ mViewManager->updateMultiCalendarDisplay();
// To make the "fill window" configurations work
mViewManager->raiseCurrentView();
@@ -686,19 +753,13 @@ void CalendarView::incidenceAdded( Incidence *incidence )
}
void CalendarView::incidenceChanged( Incidence *oldIncidence,
- Incidence *newIncidence )
-{
- incidenceChanged( oldIncidence, newIncidence, KOGlobals::UNKNOWN_MODIFIED );
-}
-
-void CalendarView::incidenceChanged( Incidence *oldIncidence,
- Incidence *newIncidence, int what )
+ Incidence *newIncidence,
+ KOGlobals::WhatChanged modification )
{
- // FIXME: Make use of the what flag, which indicates which parts of the incidence have changed!
KOIncidenceEditor *tmp = editorDialog( newIncidence );
if ( tmp ) {
kdDebug(5850) << "Incidence modified and open" << endl;
- tmp->modified( what );
+ tmp->modified();
}
setModified( true );
history()->recordEdit( oldIncidence, newIncidence );
@@ -706,14 +767,14 @@ void CalendarView::incidenceChanged( Incidence *oldIncidence,
// Record completed todos in journals, if enabled. we should to this here in
// favour of the todolist. users can mark a task as completed in an editor
// as well.
- if ( newIncidence->type() == "Todo"
- && KOPrefs::instance()->recordTodosInJournals()
- && ( what == KOGlobals::COMPLETION_MODIFIED
- || what == KOGlobals::COMPLETION_MODIFIED_WITH_RECURRENCE ) ) {
+ if ( newIncidence->type() == "Todo" &&
+ KOPrefs::instance()->recordTodosInJournals() &&
+ ( modification == KOGlobals::COMPLETION_MODIFIED ||
+ modification == KOGlobals::COMPLETION_MODIFIED_WITH_RECURRENCE ) ) {
Todo *todo = static_cast<Todo *>(newIncidence);
- if ( todo->isCompleted()
- || what == KOGlobals::COMPLETION_MODIFIED_WITH_RECURRENCE ) {
+ if ( todo->isCompleted() ||
+ modification == KOGlobals::COMPLETION_MODIFIED_WITH_RECURRENCE ) {
TQString timeStr = KGlobal::locale()->formatTime( TQTime::currentTime() );
TQString description = i18n( "To-do completed: %1 (%2)" ).arg(
newIncidence->summary() ).arg( timeStr );
@@ -729,7 +790,8 @@ void CalendarView::incidenceChanged( Incidence *oldIncidence,
journal->setSummary( i18n("Journal of %1").arg( dateStr ) );
journal->setDescription( description );
- if ( !mChanger->addIncidence( journal, this ) ) {
+ //TODO: recorded to-dos should save into the standard resource always
+ if ( !mChanger->addIncidence( journal, 0, TQString(), this ) ) {
KODialogManager::errorSaveIncidence( this, journal );
delete journal;
return;
@@ -740,7 +802,8 @@ void CalendarView::incidenceChanged( Incidence *oldIncidence,
Journal *oldJournal = journal->clone();
journal->setDescription( journal->description().append( "\n" + description ) );
- if ( !mChanger->changeIncidence( oldJournal, journal ) ) {
+ if ( !mChanger->changeIncidence( oldJournal, journal,
+ KOGlobals::DESCRIPTION_MODIFIED, this ) ) {
KODialogManager::errorSaveIncidence( this, journal );
delete journal;
return;
@@ -799,14 +862,14 @@ void CalendarView::endMultiModify()
void CalendarView::changeIncidenceDisplay( Incidence *incidence, int action )
{
- mDateNavigator->updateView();
+ mDateNavigatorContainer->updateView();
mDialogManager->updateSearchDialog();
if ( incidence ) {
// If there is an event view visible update the display
mViewManager->currentView()->changeIncidenceDisplay( incidence, action );
if ( mTodoList ) mTodoList->changeIncidenceDisplay( incidence, action );
- mEventViewer->changeIncidenceDisplay( incidence, action );
+ mEventViewer->changeIncidenceDisplay( incidence, activeDate( true ), action );
} else {
mViewManager->currentView()->updateView();
if ( mTodoList ) mTodoList->updateView();
@@ -818,12 +881,12 @@ void CalendarView::updateView(const TQDate &start, const TQDate &end)
{
mTodoList->updateView();
mViewManager->updateView(start, end);
- mDateNavigator->updateView();
+ mDateNavigatorContainer->updateView();
}
void CalendarView::updateView()
{
- DateList tmpList = mNavigator->selectedDates();
+ DateList tmpList = mDateNavigator->selectedDates();
// We assume that the navigator only selects consecutive days.
updateView( tmpList.first(), tmpList.last() );
@@ -831,7 +894,7 @@ void CalendarView::updateView()
void CalendarView::updateUnmanagedViews()
{
- mDateNavigator->updateDayMatrix();
+ mDateNavigatorContainer->updateDayMatrix();
updateView();
}
@@ -845,83 +908,205 @@ int CalendarView::msgItemDelete( Incidence *incidence )
void CalendarView::edit_cut()
{
- Incidence *incidence = selectedIncidence();
+ Incidence *incidence = incToSendToClipboard( true );
if ( !incidence || !mChanger ) {
KNotifyClient::beep();
return;
}
- mChanger->cutIncidence( incidence );
+
+ Incidence::List incidences;
+ int km = KMessageBox::Yes;
+
+ if ( !incidence->relations().isEmpty() &&
+ incidence->type() == "Todo" ) { // Only todos (yet?)
+ km = KMessageBox::questionYesNoCancel( this,
+ i18n("The item \"%1\" has sub-to-dos. "
+ "Do you want to cut just this item and "
+ "make all its sub-to-dos independent, or "
+ "cut the to-do with all its sub-to-dos?"
+ ).arg( incidence->summary() ),
+ i18n("KOrganizer Confirmation"),
+ i18n("Cut Only This"),
+ i18n("Cut All"));
+ }
+
+ if ( km == KMessageBox::Yes ) { // only one
+ incidences.append( incidence );
+ makeChildrenIndependent( incidence );
+ } else if ( km == KMessageBox::No ) { // all
+ // load incidence + children + grandchildren...
+ getIncidenceHierarchy( incidence, incidences );
+ }
+
+ if ( km != KMessageBox::Cancel ) {
+ mChanger->cutIncidences( incidences, this );
+ }
}
void CalendarView::edit_copy()
{
- Incidence *incidence = selectedIncidence();
+ Incidence *incidence = incToSendToClipboard( false );
- if (!incidence) {
+ if ( !incidence ) {
KNotifyClient::beep();
return;
}
- DndFactory factory( mCalendar );
- if ( !factory.copyIncidence( incidence ) ) {
- KNotifyClient::beep();
+
+ Incidence::List incidences;
+ int km = KMessageBox::Yes;
+
+ if ( !incidence->relations().isEmpty() &&
+ incidence->type() == "Todo" ) { // only todos.
+ km = KMessageBox::questionYesNoCancel( this,
+ i18n("The item \"%1\" has sub-to-dos. "
+ "Do you want to copy just this item or "
+ "copy the to-do with all its sub-to-dos?"
+ ).arg( incidence->summary() ),
+ i18n("KOrganizer Confirmation"),
+ i18n("Copy Only This"),
+ i18n("Copy All"));
+ }
+
+ if ( km == KMessageBox::Yes ) { // only one
+ incidences.append( incidence );
+ } else if ( km == KMessageBox::No ) { // all
+ // load incidence + children + grandchildren...
+ getIncidenceHierarchy( incidence, incidences );
+ }
+
+ if ( km != KMessageBox::Cancel ) {
+ DndFactory factory( mCalendar );
+ if ( !factory.copyIncidences( incidences ) ) {
+ KNotifyClient::beep();
+ }
+ }
+}
+
+Incidence* CalendarView::incToSendToClipboard( bool cut )
+{
+ Incidence *originalInc = selectedIncidence();
+
+ if ( originalInc && originalInc->doesRecur() &&
+ originalInc->type() == "Event" ) { // temporary, until recurring to-dos are fixed
+
+ Incidence *inc;
+ KOGlobals::WhichOccurrences chosenOption;
+ if ( cut ) {
+ inc = singleOccurrenceOrAll( originalInc, KOGlobals::CUT, chosenOption, TQDate(), true );
+ } else {
+ // The user is copying, the original incidence can't be changed
+ // we can only dissociate a copy
+ Incidence *originalIncSaved = originalInc->clone();
+ inc = singleOccurrenceOrAll( originalIncSaved, KOGlobals::COPY, chosenOption, TQDate(), false );
+
+ // no dissociation, no need to leak our clone
+ if ( chosenOption == KOGlobals::ALL ) {
+ inc = originalInc;
+ delete originalIncSaved;
+ }
+
+ // no need to leak our clone
+ if ( chosenOption == KOGlobals::NONE ) {
+ delete originalIncSaved;
+ }
+ }
+
+ return inc;
+ } else {
+ return originalInc;
}
}
void CalendarView::edit_paste()
{
-// If in agenda view, use the selected time and date from there.
-// In all other cases, paste the event on the first day of the
-// selection in the day matrix on the left
+// If in agenda and month view, use the selected time and date from there.
+// In all other cases, use the navigator's selected date.
- TQDate date;
- // create an invalid time to check if we got a new time for the eevent
- TQTime time(-1,-1);
- TQDateTime startDT, endDT;
+ TQDate date; // null dates are invalid, that's what we want
+ bool timeSet = false;// flag denoting if the time has been set.
+ TQTime time; // null dates are valid, so rely on the timeSet flag
+ TQDateTime endDT; // null datetimes are invalid, that's what we want
bool useEndTime = false;
+ KOrg::BaseView *curView = mViewManager->currentView();
+
KOAgendaView *aView = mViewManager->agendaView();
- if (aView && aView->selectionStart().isValid()) {
- date = aView->selectionStart().date();
- startDT = aView->selectionStart();
+ KOMonthView *mView = mViewManager->monthView();
+ if ( curView == mViewManager->multiAgendaView() ) {
+ aView = mViewManager->multiAgendaView()->selectedAgendaView();
+ curView = aView;
+ }
+
+ if ( !curView ) {
+ return;
+ }
+
+ if ( curView == aView && aView->selectionStart().isValid() ) {
+ date = aView->selectionStart().date();
endDT = aView->selectionEnd();
useEndTime = !aView->selectedIsSingleCell();
- if (!aView->selectedIsAllDay()) {
- time = aView->selectionStart().time();
+ if ( !aView->selectedIsAllDay() ) {
+ time = aView->selectionStart().time();
+ timeSet = true;
}
+ } else if ( curView == mView && mView->selectionStart().isValid() ) {
+ date = mView->selectionStart().date();
+ } else if ( !mDateNavigator->selectedDates().isEmpty() &&
+ curView->supportsDateNavigation() ) {
+ // default to the selected date from the navigator
+ date = mDateNavigator->selectedDates().first();
+ }
+
+ if ( !date.isValid() && curView->supportsDateNavigation() ) {
+ KMessageBox::sorry(
+ this,
+ i18n( "Paste failed: unable to determine a valid target date." ) );
+ return;
+ }
+ DndFactory factory( mCalendar );
+ Incidence::List pastedIncidences;
+ if ( timeSet && time.isValid() ) {
+ pastedIncidences = factory.pasteIncidences( date, &time );
} else {
- date = mNavigator->selectedDates().first();
+ pastedIncidences = factory.pasteIncidences( date );
}
- DndFactory factory( mCalendar );
- Incidence *pastedIncidence;
- if (time.isValid())
- pastedIncidence = factory.pasteIncidence( date, &time );
- else
- pastedIncidence = factory.pasteIncidence( date );
- if ( !pastedIncidence ) return;
-
- // FIXME: use a visitor here
- if (pastedIncidence->type() == "Event" ) {
-
- Event* pastedEvent = static_cast<Event*>(pastedIncidence);
- // only use selected area if event is of the same type (all-day or non-all-day
- // as the current selection is
- if ( aView && endDT.isValid() && useEndTime ) {
- if ( (pastedEvent->doesFloat() && aView->selectedIsAllDay()) ||
- (!pastedEvent->doesFloat() && ! aView->selectedIsAllDay()) ) {
- pastedEvent->setDtEnd(endDT);
+ Incidence::List::Iterator it;
+ for ( it = pastedIncidences.begin(); it != pastedIncidences.end(); ++it ) {
+ QPair<ResourceCalendar *, TQString>p = viewSubResourceCalendar();
+
+ // FIXME: use a visitor here
+ if ( ( *it )->type() == "Event" ) {
+ Event *pastedEvent = static_cast<Event*>( *it );
+ // only use selected area if event is of the same type
+ // (all-day or non-all-day) as the current selection is
+ if ( aView && endDT.isValid() && useEndTime ) {
+ if ( ( pastedEvent->doesFloat() && aView->selectedIsAllDay() ) ||
+ ( !pastedEvent->doesFloat() && !aView->selectedIsAllDay() ) ) {
+ pastedEvent->setDtEnd( endDT );
+ }
}
- }
- mChanger->addIncidence( pastedEvent, this );
- } else if ( pastedIncidence->type() == "Todo" ) {
- Todo* pastedTodo = static_cast<Todo*>(pastedIncidence);
- Todo* _selectedTodo = selectedTodo();
- if ( _selectedTodo )
- pastedTodo->setRelatedTo( _selectedTodo );
- mChanger->addIncidence( pastedTodo, this );
+ // KCal supports events with relations, but korganizer doesn't
+ // so unset it. It can even come from other application.
+ pastedEvent->setRelatedTo( 0 );
+ pastedEvent->setRelatedToUid( TQString() );
+
+ mChanger->addIncidence( pastedEvent, p.first, p.second, this );
+
+ } else if ( ( *it )->type() == "Todo" ) {
+ Todo *pastedTodo = static_cast<Todo*>( *it );
+ Todo *_selectedTodo = selectedTodo();
+
+ // if we are cutting a hierarchy only the root
+ // should be son of _selectedTodo
+ if ( _selectedTodo && !pastedTodo->relatedTo() ) {
+ pastedTodo->setRelatedTo( _selectedTodo );
+ }
+ mChanger->addIncidence( pastedTodo, p.first, p.second, this );
+ }
}
}
@@ -932,26 +1117,22 @@ void CalendarView::edit_options()
void CalendarView::dateTimesForNewEvent( TQDateTime &startDt, TQDateTime &endDt, bool &allDay )
{
- if ( !startDt.isValid() ) {
- // Default start is the first selected date with the preferred time as set
- // in the config dlg.
- if ( !startDt.date().isValid() ) {
- startDt.setDate( mNavigator->selectedDates().first() );
- }
- if ( !startDt.time().isValid() ) {
- startDt.setTime( KOPrefs::instance()->mStartTime.time() );
- }
- }
- if ( !endDt.isValid() ) {
- int addSecs = ( KOPrefs::instance()->mDefaultDuration.time().hour()*3600 ) +
- ( KOPrefs::instance()->mDefaultDuration.time().minute()*60 );
+ mViewManager->currentView()->eventDurationHint( startDt, endDt, allDay );
+
+ if ( !startDt.isValid() || !endDt.isValid() ) {
+ startDt.setDate( activeDate( true ) );
+ startDt.setTime( KOPrefs::instance()->mStartTime.time() );
+
+ int addSecs = ( KOPrefs::instance()->mDefaultDuration.time().hour() * 3600 ) +
+ ( KOPrefs::instance()->mDefaultDuration.time().minute() * 60 );
+
endDt = startDt.addSecs( addSecs );
}
- mViewManager->currentView()->eventDurationHint( startDt, endDt, allDay );
}
-KOEventEditor *CalendarView::newEventEditor( const TQDateTime &startDtParam,
- const TQDateTime &endDtParam, bool allDayParam)
+KOEventEditor *CalendarView::newEventEditor( ResourceCalendar *res, const TQString &subRes,
+ const TQDateTime &startDtParam,
+ const TQDateTime &endDtParam, bool allDayParam )
{
// let the current view change the default start/end datetime
bool allDay = allDayParam;
@@ -963,111 +1144,164 @@ KOEventEditor *CalendarView::newEventEditor( const TQDateTime &startDtParam,
KOEventEditor *eventEditor = mDialogManager->getEventEditor();
eventEditor->newEvent();
connectIncidenceEditor( eventEditor );
+ eventEditor->setResource( res, subRes );
eventEditor->setDates( startDt, endDt, allDay );
mDialogManager->connectTypeAhead( eventEditor, dynamic_cast<KOrg::AgendaView*>(viewManager()->currentView()) );
return eventEditor;
}
+void CalendarView::newEvent()
+{
+ KOrg::BaseView *currentView = mViewManager->currentView();
+ if ( currentView == mViewManager->multiAgendaView() ) {
+ currentView = mViewManager->multiAgendaView()->selectedAgendaView();
+ }
+ if ( currentView ) {
+ newEvent( currentView->resourceCalendar(),
+ currentView->subResourceCalendar() );
+ }
+}
-void CalendarView::newEvent()
+void CalendarView::newEvent( ResourceCalendar *res, const TQString &subRes )
{
kdDebug(5850) << "CalendarView::newEvent()" << endl;
- newEvent( TQDateTime(), TQDateTime() );
+ newEvent( res, subRes, TQDateTime(), TQDateTime() );
}
-void CalendarView::newEvent( const TQDate &dt )
+void CalendarView::newEvent( ResourceCalendar *res, const TQString &subRes,
+ const TQDate &dt )
{
TQDateTime startDt( dt, KOPrefs::instance()->mStartTime.time() );
- return newEvent( TQDateTime( dt ), TQDateTime() );
+ newEvent( res, subRes, TQDateTime( dt ), TQDateTime() );
}
-void CalendarView::newEvent( const TQDateTime &startDt )
+void CalendarView::newEvent( ResourceCalendar *res, const TQString &subRes,
+ const TQDateTime &startDt )
{
- return newEvent( startDt, TQDateTime() );
+ newEvent( res, subRes, startDt, TQDateTime() );
}
-void CalendarView::newEvent( const TQDateTime &startDt, const TQDateTime &endDt,
+void CalendarView::newEvent( ResourceCalendar *res, const TQString &subRes,
+ const TQDateTime &startDt, const TQDateTime &endDt,
bool allDay )
{
- KOEventEditor *eventEditor = newEventEditor( startDt, endDt, allDay );
+ KOEventEditor *eventEditor = newEventEditor( res, subRes,
+ startDt, endDt, allDay );
eventEditor->show();
}
-void CalendarView::newEvent( const TQString &summary, const TQString &description,
+void CalendarView::newEvent( ResourceCalendar *res, const TQString &subRes,
+ const TQString &summary, const TQString &description,
const TQStringList &attachments, const TQStringList &attendees,
const TQStringList &attachmentMimetypes, bool inlineAttachment )
{
- KOEventEditor *eventEditor = newEventEditor();
+ KOEventEditor *eventEditor = newEventEditor( res, subRes );
eventEditor->setTexts( summary, description );
// if attach or attendee list is empty, these methods don't do anything, so
- // it's save to call them in every case
+ // it's safe to call them in every case
eventEditor->addAttachments( attachments, attachmentMimetypes, inlineAttachment );
eventEditor->addAttendees( attendees );
eventEditor->show();
}
-void CalendarView::newTodo( const TQString &summary, const TQString &description,
+void CalendarView::newTodo( ResourceCalendar *res, const TQString &subRes,
+ const TQString &summary, const TQString &description,
const TQStringList &attachments, const TQStringList &attendees,
- const TQStringList &attachmentMimetypes, bool inlineAttachment )
+ const TQStringList &attachmentMimetypes,
+ bool inlineAttachment, bool isTask )
{
kdDebug(5850) << k_funcinfo << endl;
KOTodoEditor *todoEditor = mDialogManager->getTodoEditor();
connectIncidenceEditor( todoEditor );
todoEditor->newTodo();
+ todoEditor->setResource( res, subRes );
todoEditor->setTexts( summary, description );
todoEditor->addAttachments( attachments, attachmentMimetypes, inlineAttachment );
todoEditor->addAttendees( attendees );
+ todoEditor->selectCreateTask( isTask );
todoEditor->show();
}
void CalendarView::newTodo()
{
+ KOrg::BaseView *currentView = mViewManager->currentView();
+
+ if ( currentView == mViewManager->multiAgendaView() ) {
+ currentView = mViewManager->multiAgendaView()->selectedAgendaView();
+ }
+ if ( currentView ) {
+ newTodo( currentView->resourceCalendar(),
+ currentView->subResourceCalendar() );
+ }
+}
+
+void CalendarView::newTodo( ResourceCalendar *res, const TQString &subRes )
+{
kdDebug(5850) << k_funcinfo << endl;
TQDateTime dtDue;
bool allday = true;
KOTodoEditor *todoEditor = mDialogManager->getTodoEditor();
connectIncidenceEditor( todoEditor );
todoEditor->newTodo();
+ todoEditor->setResource( res, subRes );
if ( mViewManager->currentView()->isEventView() ) {
- dtDue.setDate( mNavigator->selectedDates().first() );
+ dtDue.setDate( mDateNavigator->selectedDates().first() );
TQDateTime dtDummy = TQDateTime::currentDateTime();
- mViewManager->currentView()->
- eventDurationHint( dtDue, dtDummy, allday );
+ mViewManager->currentView()->eventDurationHint( dtDue, dtDummy, allday );
todoEditor->setDates( dtDue, allday );
}
todoEditor->show();
}
-void CalendarView::newTodo( const TQDate &date )
+void CalendarView::newTodo( ResourceCalendar *res, const TQString &subRes,
+ const TQDate &date )
{
KOTodoEditor *todoEditor = mDialogManager->getTodoEditor();
connectIncidenceEditor( todoEditor );
todoEditor->newTodo();
+ todoEditor->setResource( res, subRes );
todoEditor->setDates( TQDateTime( date, TQTime::currentTime() ), true );
todoEditor->show();
}
void CalendarView::newJournal()
{
+ KOrg::BaseView *currentView = mViewManager->currentView();
+
+ if ( currentView == mViewManager->multiAgendaView() ) {
+ currentView = mViewManager->multiAgendaView()->selectedAgendaView();
+ }
+
+ if ( currentView ) {
+ newJournal( currentView->resourceCalendar(),
+ currentView->subResourceCalendar() );
+ }
+}
+
+void CalendarView::newJournal( ResourceCalendar *res, const TQString &subRes )
+{
kdDebug(5850) << "CalendarView::newJournal()" << endl;
- newJournal( TQString::null, TQDate() );
+ newJournal( res, subRes, TQString::null, TQDate() );
}
-void CalendarView::newJournal( const TQDate &date)
+void CalendarView::newJournal( ResourceCalendar *res, const TQString &subRes,
+ const TQDate &date)
{
- newJournal( TQString::null, date );
+ newJournal( res, subRes, TQString::null, date );
}
-void CalendarView::newJournal( const TQString &text, const TQDate &date )
+void CalendarView::newJournal( ResourceCalendar *res, const TQString &subRes,
+ const TQString &text, const TQDate &date )
{
KOJournalEditor *journalEditor = mDialogManager->getJournalEditor();
connectIncidenceEditor( journalEditor );
journalEditor->newJournal();
+ journalEditor->setResource( res, subRes );
journalEditor->setTexts( text );
if ( !date.isValid() ) {
- journalEditor->setDate( mNavigator->selectedDates().first() );
+ journalEditor->setDate( mDateNavigator->selectedDates().first() );
} else {
journalEditor->setDate( date );
}
@@ -1089,15 +1323,6 @@ void CalendarView::newSubTodo(Todo *parentEvent)
todoEditor->show();
}
-void CalendarView::newFloatingEvent()
-{
- DateList tmpList = mNavigator->selectedDates();
- TQDate date = tmpList.first();
-
- newEvent( TQDateTime( date, TQTime( 12, 0, 0 ) ),
- TQDateTime( date, TQTime( 12, 0, 0 ) ), true );
-}
-
bool CalendarView::addIncidence( const TQString &ical )
{
kdDebug(5850) << "CalendarView::addIncidence:\n" << ical << endl;
@@ -1105,7 +1330,7 @@ bool CalendarView::addIncidence( const TQString &ical )
format.setTimeZone( mCalendar->timeZoneId(), true );
Incidence *incidence = format.fromString( ical );
if ( !incidence ) return false;
- if ( !mChanger->addIncidence( incidence, this ) ) {
+ if ( !mChanger->addIncidence( incidence, 0, TQString(), this ) ) {
delete incidence;
return false;
}
@@ -1115,19 +1340,21 @@ bool CalendarView::addIncidence( const TQString &ical )
void CalendarView::appointment_show()
{
Incidence *incidence = selectedIncidence();
- if (incidence)
- showIncidence( incidence );
- else
+ if ( incidence ) {
+ showIncidence( incidence, activeIncidenceDate() );
+ } else {
KNotifyClient::beep();
+ }
}
void CalendarView::appointment_edit()
{
Incidence *incidence = selectedIncidence();
- if (incidence)
- editIncidence( incidence );
- else
+ if ( incidence ) {
+ editIncidence( incidence, activeIncidenceDate() );
+ } else {
KNotifyClient::beep();
+ }
}
void CalendarView::appointment_delete()
@@ -1142,22 +1369,24 @@ void CalendarView::appointment_delete()
void CalendarView::todo_unsub()
{
Todo *anTodo = selectedTodo();
- if( todo_unsub (anTodo ) ) {
+ if( incidence_unsub ( anTodo ) ) {
updateView();
}
}
-bool CalendarView::todo_unsub( Todo *todo )
+bool CalendarView::incidence_unsub( Incidence *inc )
{
- bool status= false;
- if ( !todo || !todo->relatedTo() ) return false;
+ bool status = false;
+ if ( !inc || !inc->relatedTo() ) {
+ return false;
+ }
- if ( mChanger->beginChange( todo ) ) {
- Todo *oldTodo = todo->clone();
- todo->setRelatedTo(0);
- mChanger->changeIncidence( oldTodo, todo, KOGlobals::RELATION_MODIFIED );
- mChanger->endChange( todo );
- delete oldTodo;
+ if ( mChanger->beginChange( inc, 0, TQString() ) ) {
+ Incidence *oldInc = inc->clone();
+ inc->setRelatedTo( 0 );
+ mChanger->changeIncidence( oldInc, inc, KOGlobals::RELATION_MODIFIED, this );
+ mChanger->endChange( inc, 0, TQString() );
+ delete oldInc;
setModified(true);
status = true;
}
@@ -1169,34 +1398,30 @@ bool CalendarView::todo_unsub( Todo *todo )
return status;
}
-bool CalendarView::makeSubTodosIndependents ( )
+bool CalendarView::makeSubTodosIndependent ( )
{
bool status = false;
- Todo *anTodo = selectedTodo();
+ Todo *aTodo = selectedTodo();
- if( makeSubTodosIndependents( anTodo ) ) {
+ if ( makeChildrenIndependent( aTodo ) ) {
updateView();
status = true;
}
return status;
}
-bool CalendarView::makeSubTodosIndependents ( Todo *todo )
+bool CalendarView::makeChildrenIndependent ( Incidence *inc )
{
- if( !todo || todo->relations().isEmpty() ) return false;
+ if ( !inc || inc->relations().isEmpty() ) {
+ return false;
+ }
startMultiModify ( i18n( "Make sub-to-dos independent" ) );
- Incidence::List subTodos( todo->relations() );
+ Incidence::List subIncs( inc->relations() );
Incidence::List::Iterator it;
- Incidence *aIncidence;
- Todo *aTodo;
- for ( it= subTodos.begin(); it != subTodos.end(); ++it ) {
- aIncidence = *it;
- if( aIncidence && aIncidence->type() == "Todo" ) {
- aTodo = static_cast<Todo*>( aIncidence );
- todo_unsub ( aTodo );
- }
+ for ( it= subIncs.begin(); it != subIncs.end(); ++it ) {
+ incidence_unsub ( *it );
}
endMultiModify();
return true;
@@ -1220,7 +1445,7 @@ void CalendarView::toggleAlarm( Incidence *incidence )
return;
}
Incidence*oldincidence = incidence->clone();
- if ( !mChanger->beginChange( incidence ) ) {
+ if ( !mChanger->beginChange( incidence, 0, TQString() ) ) {
kdDebug(5850) << "Unable to lock incidence " << endl;
delete oldincidence;
return;
@@ -1228,15 +1453,35 @@ void CalendarView::toggleAlarm( Incidence *incidence )
Alarm::List alarms = incidence->alarms();
Alarm::List::ConstIterator it;
- for( it = alarms.begin(); it != alarms.end(); ++it )
+ for ( it = alarms.begin(); it != alarms.end(); ++it ) {
(*it)->toggleAlarm();
- if (alarms.isEmpty()) {
+ }
+ if ( alarms.isEmpty() ) {
// Add an alarm if it didn't have one
- Alarm*alm = incidence->newAlarm();
- alm->setEnabled(true);
+ Alarm *alm = incidence->newAlarm();
+ alm->setType( Alarm::Display );
+ alm->setEnabled( true );
+ int duration; // in secs
+ switch( KOPrefs::instance()->mReminderTimeUnits ) {
+ default:
+ case 0: // mins
+ duration = KOPrefs::instance()->mReminderTime * 60;
+ break;
+ case 1: // hours
+ duration = KOPrefs::instance()->mReminderTime * 60 * 60;
+ break;
+ case 2: // days
+ duration = KOPrefs::instance()->mReminderTime * 60 * 60 * 24;
+ break;
+ }
+ if ( incidence->type() == "Event" ) {
+ alm->setStartOffset( KCal::Duration( -duration ) );
+ } else {
+ alm->setEndOffset( KCal::Duration( -duration ) );
+ }
}
- mChanger->changeIncidence( oldincidence, incidence, KOGlobals::ALARM_MODIFIED );
- mChanger->endChange( incidence );
+ mChanger->changeIncidence( oldincidence, incidence, KOGlobals::ALARM_MODIFIED, this );
+ mChanger->endChange( incidence, 0, TQString() );
delete oldincidence;
// mClickedItem->updateIcons();
@@ -1248,7 +1493,11 @@ void CalendarView::dissociateOccurrence( Incidence *incidence, const TQDate &dat
kdDebug(5850) << "CalendarView::toggleAlarm() called without having a clicked item" << endl;
return;
}
- if ( !mChanger->beginChange( incidence ) ) {
+
+ QPair<ResourceCalendar *, TQString>p =
+ CalHelper::incSubResourceCalendar( calendar(), incidence );
+
+ if ( !mChanger->beginChange( incidence, p.first, p.second ) ) {
kdDebug(5850) << "Unable to lock incidence " << endl;
return;
}
@@ -1260,14 +1509,14 @@ void CalendarView::dissociateOccurrence( Incidence *incidence, const TQDate &dat
if ( newInc ) {
// TODO [FIXME]: Use the same resource instead of asking again!
// See also koagenda.cpp: endItemAction()
- bool success = mChanger->addIncidence( newInc, this );
+ bool success = mChanger->addIncidence( newInc, p.first, p.second, this );
if ( success )
- mChanger->changeIncidence( oldincidence, incidence );
+ mChanger->changeIncidence( oldincidence, incidence, KOGlobals::NOTHING_MODIFIED, this );
} else {
KMessageBox::sorry( this, i18n("Dissociating the occurrence failed."),
i18n("Dissociating Failed") );
}
- mChanger->endChange( incidence );
+ mChanger->endChange( incidence, p.first, p.second );
endMultiModify();
delete oldincidence;
}
@@ -1278,7 +1527,11 @@ void CalendarView::dissociateFutureOccurrence( Incidence *incidence, const TQDat
kdDebug(5850) << "CalendarView::toggleAlarm() called without having a clicked item" << endl;
return;
}
- if ( !mChanger->beginChange( incidence ) ) {
+
+ QPair<ResourceCalendar *, TQString>p =
+ CalHelper::incSubResourceCalendar( calendar(), incidence );
+
+ if ( !mChanger->beginChange( incidence, p.first, p.second ) ) {
kdDebug(5850) << "Unable to lock incidence " << endl;
return;
}
@@ -1287,15 +1540,14 @@ void CalendarView::dissociateFutureOccurrence( Incidence *incidence, const TQDat
Incidence* newInc = mCalendar->dissociateOccurrence( incidence, date, true );
if ( newInc ) {
- // TODO: Use the same resource instead of asking again!
- mChanger->changeIncidence( oldincidence, incidence );
- mChanger->addIncidence( newInc, this );
+ mChanger->changeIncidence( oldincidence, incidence, KOGlobals::NOTHING_MODIFIED, this );
+ mChanger->addIncidence( newInc, p.first, p.second, this );
} else {
KMessageBox::sorry( this, i18n("Dissociating the future occurrences failed."),
i18n("Dissociating Failed") );
}
endMultiModify();
- mChanger->endChange( incidence );
+ mChanger->endChange( incidence, p.first, p.second );
delete oldincidence;
}
@@ -1374,29 +1626,43 @@ void CalendarView::schedule_declinecounter(Incidence *incidence)
schedule(Scheduler::Declinecounter,incidence);
}
-void CalendarView::schedule_forward(Incidence * incidence)
+void CalendarView::schedule_forward( Incidence *incidence )
{
- if (incidence == 0)
+ if ( !incidence ) {
incidence = selectedIncidence();
+ }
- if (!incidence) {
- KMessageBox::information( this, i18n("No item selected."),
- "ForwardNoEventSelected" );
+ if ( !incidence ) {
+ KMessageBox::information(
+ this,
+ i18n( "No item selected." ),
+ i18n( "Forwarding" ),
+ "ForwardNoEventSelected" );
return;
}
PublishDialog publishdlg;
if ( publishdlg.exec() == TQDialog::Accepted ) {
TQString recipients = publishdlg.addresses();
+ if ( incidence->organizer().isEmpty() ) {
+ incidence->setOrganizer( Person( KOPrefs::instance()->fullName(),
+ KOPrefs::instance()->email() ) );
+ }
+
ICalFormat format;
TQString messageText = format.createScheduleMessage( incidence, Scheduler::Request );
KOMailClient mailer;
if ( mailer.mailTo( incidence, recipients, messageText ) ) {
-
- KMessageBox::information( this, i18n("The item information was successfully sent."),
- i18n("Forwarding"), "IncidenceForwardSuccess" );
+ KMessageBox::information(
+ this,
+ i18n( "The item information was successfully sent." ),
+ i18n( "Forwarding" ),
+ "IncidenceForwardSuccess" );
} else {
- KMessageBox::error( this, i18n("Unable to forward the item '%1'").arg( incidence->summary() ) );
+ KMessageBox::error(
+ this,
+ i18n( "Unable to forward the item '%1'" ).arg( incidence->summary() ),
+ i18n( "Forwarding Error" ) );
}
}
}
@@ -1458,7 +1724,7 @@ void CalendarView::schedule(Scheduler::Method method, Incidence *incidence)
// Send the mail
KCal::MailScheduler scheduler( mCalendar );
- if ( !scheduler.performTransaction( incidence, method ) ) {
+ if ( scheduler.performTransaction( incidence, method ) ) {
KMessageBox::information( this, i18n("The groupware message for item '%1'"
"was successfully sent.\nMethod: %2")
.arg( incidence->summary() )
@@ -1515,9 +1781,11 @@ void CalendarView::print()
KOrg::BaseView *currentView = mViewManager->currentView();
CalPrinterBase::PrintType printType = CalPrinterBase::Month;
- if ( currentView ) printType = currentView->printType();
+ if ( currentView ) {
+ printType = currentView->printType();
+ }
- DateList tmpDateList = mNavigator->selectedDates();
+ DateList tmpDateList = mDateNavigator->selectedDates();
Incidence::List selectedIncidences;
if ( mViewManager->currentView() ) {
selectedIncidences = mViewManager->currentView()->selectedIncidences();
@@ -1542,12 +1810,20 @@ void CalendarView::exportWeb()
void CalendarView::exportICalendar()
{
TQString 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 );
- storage.save();
+ if ( !filename.isEmpty() )
+ {
+ // Force correct extension
+ if (filename.right(4) != ".ics") filename += ".ics";
+ if ( TQFile( filename ).exists() ) {
+ if ( KMessageBox::No == KMessageBox::warningYesNo(
+ this,
+ i18n( "Do you want to overwrite %1?").arg(filename) ) ) {
+ return;
+ }
+ }
+ FileStorage storage( mCalendar, filename, new ICalFormat );
+ storage.save();
+ }
}
void CalendarView::exportVCalendar()
@@ -1561,13 +1837,21 @@ void CalendarView::exportVCalendar()
}
TQString filename = KFileDialog::getSaveFileName("vcalout.vcs",i18n("*.vcs|vCalendars"),this);
-
- // TODO: I don't like forcing extensions:
- // Force correct extension
- if (filename.right(4) != ".vcs") filename += ".vcs";
-
- FileStorage storage( mCalendar, filename, new VCalFormat );
- storage.save();
+ if ( !filename.isEmpty() )
+ {
+ // TODO: I don't like forcing extensions:
+ // Force correct extension
+ if (filename.right(4) != ".vcs") filename += ".vcs";
+ if ( TQFile( filename ).exists() ) {
+ if ( KMessageBox::No == KMessageBox::warningYesNo(
+ this,
+ i18n( "Do you want to overwrite %1?").arg(filename ) ) ) {
+ return;
+ }
+ }
+ FileStorage storage( mCalendar, filename, new VCalFormat );
+ storage.save();
+ }
}
void CalendarView::eventUpdated(Incidence *)
@@ -1592,41 +1876,54 @@ void CalendarView::adaptNavigationUnits()
}
}
-void CalendarView::processMainViewSelection( Incidence *incidence )
+void CalendarView::processMainViewSelection( Incidence *incidence, const TQDate &date )
{
if ( incidence ) mTodoList->clearSelection();
- processIncidenceSelection( incidence );
+ processIncidenceSelection( incidence, date );
}
-void CalendarView::processTodoListSelection( Incidence *incidence )
+void CalendarView::processTodoListSelection( Incidence *incidence, const TQDate &date )
{
if ( incidence && mViewManager->currentView() ) {
mViewManager->currentView()->clearSelection();
}
- processIncidenceSelection( incidence );
+ processIncidenceSelection( incidence, date );
}
-void CalendarView::processIncidenceSelection( Incidence *incidence )
+void CalendarView::processIncidenceSelection( Incidence *incidence, const TQDate &date )
{
- if ( incidence == mSelectedIncidence ) return;
+ if ( incidence != mSelectedIncidence ) {
+ // This signal also must be emitted if incidence is 0
+ emit incidenceSelected( incidence, date );
+ }
+
+ if ( !incidence ) {
+ mSelectedIncidence = incidence;
+ return;
+ }
+ if ( incidence == mSelectedIncidence ) {
+ if ( !incidence->doesRecur() || mSaveDate == date ) {
+ return;
+ }
+ }
mSelectedIncidence = incidence;
+ mSaveDate = date;
- emit incidenceSelected( mSelectedIncidence );
+ emit incidenceSelected( mSelectedIncidence, date );
bool organizerEvents = false;
bool groupEvents = false;
bool todo = false;
bool subtodo = false;
- if ( incidence ) {
- organizerEvents = KOPrefs::instance()->thatIsMe( incidence->organizer().email() );
- groupEvents = incidence->attendeeByMails( KOPrefs::instance()->allEmails() );
+ organizerEvents = KOPrefs::instance()->thatIsMe( incidence->organizer().email() );
+ groupEvents = incidence->attendeeByMails( KOPrefs::instance()->allEmails() );
- if ( incidence && incidence->type() == "Todo" ) {
- todo = true;
- subtodo = ( incidence->relatedTo() != 0 );
- }
+ if ( incidence->type() == "Todo" ) {
+ todo = true;
+ subtodo = ( incidence->relatedTo() != 0 );
}
+
emit todoSelected( todo );
emit subtodoSelected( subtodo );
emit organizerEventsSelected( organizerEvents );
@@ -1647,9 +1944,10 @@ void CalendarView::checkClipboard()
#endif
}
-void CalendarView::showDates(const DateList &selectedDates)
+void CalendarView::showDates( const DateList &selectedDates, const TQDate &preferredMonth )
{
-// kdDebug(5850) << "CalendarView::selectDates()" << endl;
+ mDateNavigatorContainer->selectDates( selectedDates, preferredMonth );
+ mNavigatorBar->selectDates( selectedDates );
if ( mViewManager->currentView() ) {
updateView( selectedDates.first(), selectedDates.last() );
@@ -1663,7 +1961,7 @@ void CalendarView::editFilters()
kdDebug(5850) << "CalendarView::editFilters()" << endl;
CalFilter *filter = mFilters.first();
- while(filter) {
+ while( filter ) {
kdDebug(5850) << " Filter: " << filter->name() << endl;
filter = mFilters.next();
}
@@ -1755,9 +2053,9 @@ void CalendarView::showIntro()
void CalendarView::showDateNavigator( bool show )
{
if( show )
- mDateNavigator->show();
+ mDateNavigatorContainer->show();
else
- mDateNavigator->hide();
+ mDateNavigatorContainer->hide();
}
void CalendarView::showTodoView( bool show )
@@ -1835,7 +2133,7 @@ Todo *CalendarView::selectedTodo()
void CalendarView::dialogClosing( Incidence *in )
{
// FIXME: this doesn't work, because if it's a new incidence, it's not locked!
- mChanger->endChange( in );
+ mChanger->endChange( in, 0, TQString() );
mDialogList.remove( in );
}
@@ -1857,18 +2155,22 @@ Incidence* CalendarView::selectedIncidence()
void CalendarView::showIncidence()
{
- showIncidence( selectedIncidence() );
+ showIncidence( selectedIncidence(), activeIncidenceDate() );
}
void CalendarView::editIncidence()
{
- editIncidence( selectedIncidence() );
+ editIncidence( selectedIncidence(), activeIncidenceDate() );
}
-bool CalendarView::editIncidence( const TQString& uid )
+bool CalendarView::editIncidence( const TQString &uid )
{
- kdDebug(5850) << "CalendarView::editIncidence()" << endl;
- return editIncidence( mCalendar->incidence( uid ) );
+ return editIncidence( mCalendar->incidence( uid ), TQDate() );
+}
+
+bool CalendarView::editIncidence( const TQString &uid, const TQDate &date )
+{
+ return editIncidence( mCalendar->incidence( uid ), date );
}
void CalendarView::deleteIncidence()
@@ -1891,21 +2193,51 @@ void CalendarView::pasteIncidence()
edit_paste();
}
-void CalendarView::showIncidence( Incidence *incidence )
+void CalendarView::showIncidence( Incidence *incidence, const TQDate &date )
{
- KOEventViewerDialog *eventViewer = new KOEventViewerDialog( this );
- eventViewer->setIncidence( incidence );
+ if ( !incidence ) {
+ return;
+ }
+
+ KOEventViewerDialog *eventViewer = new KOEventViewerDialog( calendar(), this );
+ eventViewer->setIncidence( incidence, date );
eventViewer->show();
}
-bool CalendarView::editIncidence( Incidence *incidence, bool isCounter )
+bool CalendarView::editIncidence( Incidence *incidence, const TQDate &date, bool isCounter )
{
kdDebug(5850) << "CalendarView::editEvent()" << endl;
- if ( !incidence || !mChanger ) {
+ CalendarResources *stdcal = dynamic_cast<CalendarResources *>( mCalendar );
+ if( stdcal && !stdcal->hasCalendarResources() ) {
+ KMessageBox::sorry(
+ this,
+ i18n( "No resources found. We can not edit the item." ) );
+ return false;
+ }
+
+ // FIXME: This is a nasty hack, since we need to set a parent for the
+ // resource selection dialog. However, we don't have any UI methods
+ // in the calendar, only in the CalendarResources::DestinationPolicy
+ // So we need to type-cast it and extract it from the CalendarResources
+ TQWidget *tmpparent = 0;
+ if ( stdcal ) {
+ tmpparent = stdcal->dialogParentWidget();
+ stdcal->setDialogParentWidget( this );
+ }
+
+ if ( !incidence ) {
+ kdDebug(5850) << "Empty Incidence" << endl;
KNotifyClient::beep();
return false;
}
+
+ if ( !mChanger ) {
+ kdDebug(5850) << "Empty Changer" << endl;
+ KNotifyClient::beep();
+ return false;
+ }
+
KOIncidenceEditor *tmp = editorDialog( incidence );
if ( tmp ) {
kdDebug(5850) << "CalendarView::editIncidence() in List" << endl;
@@ -1916,24 +2248,47 @@ bool CalendarView::editIncidence( Incidence *incidence, bool isCounter )
}
if ( incidence->isReadOnly() ) {
- showIncidence( incidence );
+ showIncidence( incidence, date );
return true;
}
- if ( !isCounter && !mChanger->beginChange( incidence ) ) {
- warningChangeFailed( incidence );
- showIncidence( incidence );
- return false;
+ QPair<ResourceCalendar *, TQString>p =
+ CalHelper::incSubResourceCalendar( calendar(), incidence );
+
+ Incidence *savedIncidence = incidence->clone();
+ Incidence *incToChange;
+
+ if ( incidence->doesRecur() ) {
+ KOGlobals::WhichOccurrences chosenOption;
+ incToChange = singleOccurrenceOrAll( incidence, KOGlobals::EDIT, chosenOption, date );
+ } else {
+ incToChange = incidence;
}
- kdDebug(5850) << "CalendarView::editIncidence() new IncidenceEditor" << endl;
- KOIncidenceEditor *incidenceEditor = mDialogManager->getEditor( incidence );
- connectIncidenceEditor( incidenceEditor );
+ // If the user pressed cancel incToChange is 0
+ if ( incToChange ) {
+ if ( !isCounter && !mChanger->beginChange( incToChange, p.first, p.second ) ) {
+ warningChangeFailed( incToChange );
+ showIncidence( incToChange, date );
- mDialogList.insert( incidence, incidenceEditor );
- incidenceEditor->editIncidence( incidence, mCalendar );
- incidenceEditor->show();
- return true;
+ return false;
+ }
+
+ kdDebug(5850) << "CalendarView::editIncidence() new IncidenceEditor" << endl;
+ KOIncidenceEditor *incidenceEditor = mDialogManager->getEditor( incToChange );
+ connectIncidenceEditor( incidenceEditor );
+
+ mDialogList.insert( incToChange, incidenceEditor );
+ if ( incidence != incToChange ) {
+ incidenceEditor->setRecurringIncidence( savedIncidence, incidence );
+ }
+ incidenceEditor->setResource( p.first, p.second );
+ incidenceEditor->editIncidence( incToChange, date, mCalendar );
+ incidenceEditor->show();
+ return true;
+ } else {
+ return false;
+ }
}
void CalendarView::deleteSubTodosIncidence ( Todo *todo )
@@ -1952,7 +2307,7 @@ void CalendarView::deleteSubTodosIncidence ( Todo *todo )
deleteSubTodosIncidence ( aTodo );
}
}
- mChanger->deleteIncidence ( todo );
+ mChanger->deleteIncidence ( todo, this );
}
void CalendarView::deleteTodoIncidence ( Todo *todo, bool force )
@@ -1966,29 +2321,31 @@ void CalendarView::deleteTodoIncidence ( Todo *todo, bool force )
doDelete = ( msgItemDelete( todo ) == KMessageBox::Continue );
}
if ( doDelete )
- mChanger->deleteIncidence( todo );
+ mChanger->deleteIncidence( todo, this );
return;
}
/* Ok, this to-do has sub-to-dos, ask what to do */
int km = KMessageBox::No;
if ( !force ) {
- km=KMessageBox::questionYesNoCancel( this,
- i18n("The item \"%1\" has sub-to-dos. "
- "Do you want to delete just this item and "
- "make all its sub-to-dos independent, or "
- "delete the to-do with all its sub-to-dos?"
- ).arg( todo->summary() ),
- i18n("KOrganizer Confirmation"),
- i18n("Delete Only This"),
- i18n("Delete All"));
+ km = KMessageBox::questionYesNoCancel(
+ this,
+ i18n("The item \"%1\" has sub-to-dos. "
+ "Do you want to delete just this item and "
+ "make all its sub-to-dos independent, or "
+ "delete the to-do with all its sub-to-dos?"
+ ).arg( todo->summary() ),
+ i18n("KOrganizer Confirmation"),
+ i18n("Delete Only This"),
+ i18n("Delete All"));
}
startMultiModify( i18n("Deleting sub-to-dos" ) );
// Delete only the father
if( km == KMessageBox::Yes ) {
-
- makeSubTodosIndependents ( todo );
- mChanger->deleteIncidence( todo );
+ // Instead of making a subto-do independent, why not relate
+ // it to it's dead father's parent?
+ makeChildrenIndependent ( todo );
+ mChanger->deleteIncidence( todo, this );
} else if ( km == KMessageBox::No ) {
// Delete all
// we have to hide the delete confirmation for each itemDate
@@ -2054,14 +2411,18 @@ void CalendarView::deleteIncidence(Incidence *incidence, bool force)
i18n("Delete &All"));
}
}
+
+ QPair<ResourceCalendar *, TQString>p =
+ CalHelper::incSubResourceCalendar( calendar(), incidence );
+
switch(km) {
case KMessageBox::Ok: // Continue // all
case KMessageBox::Continue:
- mChanger->deleteIncidence( incidence );
+ mChanger->deleteIncidence( incidence, this );
break;
case KMessageBox::Yes: // just this one
- if ( mChanger->beginChange( incidence ) ) {
+ if ( mChanger->beginChange( incidence, p.first, p.second ) ) {
Incidence *oldIncidence = incidence->clone();
if (incidence->recurrence()->startDate() == itemDate) {
// Moving the first in a series...don't bother with the nonstandard exclusion list
@@ -2079,18 +2440,18 @@ void CalendarView::deleteIncidence(Incidence *incidence, bool force)
// No choice but to use the exclusion list
incidence->recurrence()->addExDate( itemDate );
}
- mChanger->changeIncidence( oldIncidence, incidence );
- mChanger->endChange( incidence );
+ mChanger->changeIncidence( oldIncidence, incidence, KOGlobals::RECURRENCE_MODIFIED_ONE_ONLY, this );
+ mChanger->endChange( incidence, p.first, p.second );
delete oldIncidence;
}
break;
case KMessageBox::No: // all future items
- if ( mChanger->beginChange( incidence ) ) {
+ if ( mChanger->beginChange( incidence, p.first, p.second ) ) {
Incidence *oldIncidence = incidence->clone();
Recurrence *recur = incidence->recurrence();
recur->setEndDate( itemDate.addDays(-1) );
- mChanger->changeIncidence( oldIncidence, incidence );
- mChanger->endChange( incidence );
+ mChanger->changeIncidence( oldIncidence, incidence, KOGlobals::RECURRENCE_MODIFIED_ONE_ONLY, this );
+ mChanger->endChange( incidence, p.first, p.second );
delete oldIncidence;
}
break;
@@ -2101,8 +2462,8 @@ void CalendarView::deleteIncidence(Incidence *incidence, bool force)
doDelete = ( msgItemDelete( incidence ) == KMessageBox::Continue );
}
if ( doDelete ) {
- mChanger->deleteIncidence( incidence );
- processIncidenceSelection( 0 );
+ mChanger->deleteIncidence( incidence, this );
+ processIncidenceSelection( 0, TQDate() );
}
}
@@ -2134,7 +2495,7 @@ bool CalendarView::purgeCompletedSubTodos( Todo* todo, bool &allPurged )
if ( deleteThisTodo ) {
if ( todo->isCompleted() ) {
- if ( !mChanger->deleteIncidence( todo ) )
+ if ( !mChanger->deleteIncidence( todo, this ) )
allPurged = false;
} else {
deleteThisTodo = false;
@@ -2176,20 +2537,19 @@ void CalendarView::purgeCompleted()
}
}
-void CalendarView::slotCalendarChanged()
+void CalendarView::warningChangeFailed( Incidence *incidence )
{
- kdDebug(5850) << "CalendarView::slotCalendarChanged()" << endl;
-}
-
-void CalendarView::warningChangeFailed( Incidence * )
-{
- KMessageBox::sorry( this, i18n("Unable to edit item: "
- "it is locked by another process.") );
+ if ( incidence ) {
+ KMessageBox::sorry(
+ this,
+ i18n( "Unable to edit \"%1\" because it is locked by another process." ).
+ arg( incidence->summary() ) );
+ }
}
-void CalendarView::editCanceled( Incidence *i )
+void CalendarView::editCanceled( Incidence *incidence )
{
- mCalendar->endChange( i );
+ mCalendar->endChange( incidence );
}
void CalendarView::showErrorMessage( const TQString &msg )
@@ -2249,7 +2609,9 @@ void CalendarView::addIncidenceOn( Incidence *incadd, const TQDate &dt )
todo->setHasDueDate( true );
}
- if ( !mChanger->addIncidence( incidence, this ) ) {
+ QPair<ResourceCalendar *, TQString>p = viewSubResourceCalendar();
+
+ if ( !mChanger->addIncidence( incidence, p.first, p.second, this ) ) {
KODialogManager::errorSaveIncidence( this, incidence );
delete incidence;
}
@@ -2267,8 +2629,11 @@ void CalendarView::moveIncidenceTo( Incidence *incmove, const TQDate &dt )
addIncidenceOn( incidence, dt );
return;
}
+
Incidence *oldIncidence = incidence->clone();
- if ( !mChanger->beginChange( incidence ) ) {
+ QPair<ResourceCalendar *, TQString>p = viewSubResourceCalendar();
+
+ if ( !mChanger->beginChange( incidence, p.first, p.second ) ) {
delete oldIncidence;
return;
}
@@ -2295,15 +2660,151 @@ void CalendarView::moveIncidenceTo( Incidence *incmove, const TQDate &dt )
todo->setDtDue( due );
todo->setHasDueDate( true );
}
- mChanger->changeIncidence( oldIncidence, incidence );
- mChanger->endChange( incidence );
+ mChanger->changeIncidence( oldIncidence, incidence, KOGlobals::DATE_MODIFIED,this );
+ mChanger->endChange( incidence, p.first, p.second );
delete oldIncidence;
}
void CalendarView::resourcesChanged()
{
mViewManager->resourcesChanged();
+ mDateNavigatorContainer->setUpdateNeeded();
updateView();
}
+Incidence* CalendarView::singleOccurrenceOrAll( Incidence *inc,
+ KOGlobals::OccurrenceAction userAction,
+ KOGlobals::WhichOccurrences &chosenOption,
+ const TQDate &itemDate,
+ const bool commitToCalendar )
+{
+
+ // temporary, until recurring to-dos are fixed
+ if ( inc->type() != "Event" ) {
+ chosenOption = KOGlobals::ALL;
+ return inc;
+ }
+
+ Incidence *incToReturn = 0;
+ Incidence *incSaved = 0;
+ KOGlobals::WhatChanged whatChanged;
+
+ bool dissociationOccurred = false;
+ const TQDate &dt = itemDate.isValid() ? itemDate : activeIncidenceDate();
+
+ TQString dialogTitle;
+ TQString dialogText;
+
+ if ( userAction == KOGlobals::CUT ) {
+ dialogTitle = i18n( "Cutting Recurring Item" );
+
+ dialogText = i18n("The item you try to cut is a recurring item. Do you want to cut "
+ "only this single occurrence, only future items, "
+ "or all items in the recurrence?");
+
+ } else if ( userAction == KOGlobals::COPY ) {
+ dialogTitle = i18n( "Copying Recurring Item" );
+
+ dialogText = i18n("The item you try to copy is a recurring item. Do you want to copy "
+ "only this single occurrence, only future items, "
+ "or all items in the recurrence?");
+ } else {
+ dialogTitle = i18n( "Changing Recurring Item" );
+
+ dialogText = i18n( "The item you try to change is a recurring item. Shall the changes "
+ "be applied only to this single occurrence, only to the future items, "
+ "or to all items in the recurrence?" );
+ }
+
+ int res = KOMessageBox::fourBtnMsgBox( this, TQMessageBox::Question,
+ dialogText,
+ dialogTitle,
+ i18n("Only &This Item"), i18n("Only &Future Items"), i18n("&All Occurrences") );
+ switch ( res ) {
+ case KMessageBox::Ok: // All occurrences
+ incToReturn = inc;
+ chosenOption = KOGlobals::ALL;
+ break;
+ case KMessageBox::Yes: { // Just this occurrence
+ // Dissociate this occurrence:
+ // create clone of event, set relation to old event, set cloned event
+ // for mActionItem, add exception date to old event, changeIncidence
+ // for the old event, remove the recurrence from the new copy and then just
+ // go on with the newly adjusted mActionItem and let the usual code take
+ // care of the new time!
+
+ chosenOption = KOGlobals::ONLY_THIS_ONE;
+ whatChanged = KOGlobals::RECURRENCE_MODIFIED_ONE_ONLY;
+ startMultiModify( i18n("Dissociate event from recurrence") );
+ incSaved = inc->clone();
+ incToReturn = mCalendar->dissociateOccurrence( inc, dt );
+ if ( incToReturn ) {
+ dissociationOccurred = true;
+ } else {
+ KMessageBox::sorry( this, i18n("Unable to add the exception item to the "
+ "calendar. No change will be done."), i18n("Error Occurred") );
+ incToReturn = 0;
+ }
+
+ break; }
+ case KMessageBox::No/*Future*/: { // All future occurrences
+ // Dissociate this occurrence:
+ // create clone of event, set relation to old event, set cloned event
+ // for mActionItem, add recurrence end date to old event, changeIncidence
+ // for the old event, adjust the recurrence for the new copy and then just
+ // go on with the newly adjusted mActionItem and let the usual code take
+ // care of the new time!
+ chosenOption = KOGlobals::ONLY_FUTURE;
+ whatChanged = KOGlobals::RECURRENCE_MODIFIED_ALL_FUTURE;
+ startMultiModify( i18n("Split future recurrences") );
+ incSaved = inc->clone();
+ incToReturn = mCalendar->dissociateOccurrence( inc, dt, false );
+ if ( incToReturn ) {
+ dissociationOccurred = true;
+ } else {
+ KMessageBox::sorry( this, i18n("Unable to add the future items to the "
+ "calendar. No change will be done."), i18n("Error Occurred") );
+
+ incToReturn = 0;
+ }
+
+ break; }
+ default:
+ chosenOption = KOGlobals::NONE;
+ }
+
+ if ( dissociationOccurred && commitToCalendar ) {
+ QPair<ResourceCalendar *, TQString>p = viewSubResourceCalendar();
+ mChanger->addIncidence( incToReturn, p.first, p.second, this );
+ mChanger->changeIncidence( incSaved, inc, whatChanged, this );
+ }
+
+ return incToReturn;
+}
+
+void CalendarView::selectWeek( const TQDate &date )
+{
+ if ( KOPrefs::instance()->mWeekNumbersShowWork &&
+ mViewManager->agendaIsSelected() &&
+ mViewManager->agendaMode() == KOViewManager::AGENDA_WORK_WEEK ) {
+ mDateNavigator->selectWorkWeek( date );
+ } else {
+ mDateNavigator->selectWeek( date );
+ }
+}
+
+void CalendarView::getIncidenceHierarchy( Incidence *inc,
+ Incidence::List &children )
+{
+ // protecion against looping hierarchies
+ if ( inc && !children.contains( inc ) ) {
+ Incidence::List::ConstIterator it;
+ Incidence::List immediateChildren = inc->relations();
+ for ( it = immediateChildren.constBegin(); it != immediateChildren.constEnd(); ++it ) {
+ getIncidenceHierarchy( *it, children );
+ }
+ children.append( inc );
+ }
+}
+
#include "calendarview.moc"
diff --git a/korganizer/calendarview.h b/korganizer/calendarview.h
index dfcc75ef..5922e8f2 100644
--- a/korganizer/calendarview.h
+++ b/korganizer/calendarview.h
@@ -33,7 +33,8 @@
#include <libkcal/scheduler.h>
#include <kdepimmacros.h>
-#include <korganizer/calendarviewbase.h>
+#include "koglobals.h"
+#include "interfaces/korganizer/calendarviewbase.h"
class TQWidgetStack;
class TQSplitter;
@@ -90,7 +91,6 @@ class KDE_EXPORT CalendarView : public KOrg::CalendarViewBase, public Calendar::
CalendarView( TQWidget *parent = 0, const char *name = 0 );
virtual ~CalendarView();
-
class CalendarViewVisitor : public IncidenceBase::Visitor
{
public:
@@ -112,10 +112,11 @@ class KDE_EXPORT CalendarView : public KOrg::CalendarViewBase, public Calendar::
bool visit( Journal *journal ) { return mView->deleteJournal( journal ); }
};
-
void setCalendar( Calendar * );
Calendar *calendar();
+ QPair<ResourceCalendar *, TQString> viewSubResourceCalendar();
+
KOrg::History *history() const { return mHistory; }
KOViewManager *viewManager() const { return mViewManager; }
@@ -124,7 +125,7 @@ class KDE_EXPORT CalendarView : public KOrg::CalendarViewBase, public Calendar::
TQWidgetStack *viewStack() const { return mRightFrame; }
TQWidget *leftFrame() const { return mLeftFrame; }
NavigatorBar *navigatorBar() const { return mNavigatorBar; }
- DateNavigator *dateNavigator() const { return mNavigator; }
+ DateNavigator *dateNavigator() const { return mDateNavigator; }
KOIncidenceEditor *editorDialog( Incidence* ) const;
IncidenceChangerBase *incidenceChanger() const { return mChanger; }
@@ -182,7 +183,7 @@ class KDE_EXPORT CalendarView : public KOrg::CalendarViewBase, public Calendar::
Emitted when an incidence gets selected. If the selection is cleared the
signal is emitted with 0 as argument.
*/
- void incidenceSelected( Incidence * );
+ void incidenceSelected( Incidence *incidence, const TQDate &date );
/** Emitted, when a todoitem is selected or deselected.
the connected slots enables/disables the corresponding menu items */
void todoSelected( bool );
@@ -252,7 +253,8 @@ class KDE_EXPORT CalendarView : public KOrg::CalendarViewBase, public Calendar::
void showIncidence();
void editIncidence();
- bool editIncidence( const TQString& uid );
+ bool editIncidence( const TQString &uid );
+ bool editIncidence( const TQString &uid, const TQDate &date );
void deleteIncidence();
/**
@@ -265,29 +267,37 @@ class KDE_EXPORT CalendarView : public KOrg::CalendarViewBase, public Calendar::
*/
bool addIncidence( const TQString &ical );
- void connectIncidenceEditor( KOIncidenceEditor * );
+ void connectIncidenceEditor( KOIncidenceEditor *editor );
/** create new event without having a date hint. Takes current date as
default hint. */
void newEvent();
+ void newEvent( ResourceCalendar *res, const TQString &subRes );
/** create an editeventwin with supplied date/time, and if bool is true,
* make the event take all day. */
- void newEvent( const TQDate &startDt );
- void newEvent( const TQDateTime &startDt );
- void newEvent( const TQDateTime &startDt, const TQDateTime &EndDt, bool allDay = false );
+ void newEvent( ResourceCalendar *res, const TQString &subRes,
+ const TQDate &startDt );
+ void newEvent( ResourceCalendar *res, const TQString &subRes,
+ const TQDateTime &startDt );
+ void newEvent( ResourceCalendar *res, const TQString &subRes,
+ const TQDateTime &startDt, const TQDateTime &EndDt,
+ bool allDay = false );
/**
Create new Event from given summary, description, attachment list and
attendees list
*/
- void newEvent( const TQString &summary, const TQString &description = TQString::null,
- const TQStringList &attachment = TQStringList(), const TQStringList &attendees = TQStringList(),
- const TQStringList &attachmentMimetypes = TQStringList(), bool inlineAttachment = false );
- void newFloatingEvent();
+ void newEvent( ResourceCalendar *res, const TQString &subRes,
+ const TQString &summary,
+ const TQString &description = TQString::null,
+ const TQStringList &attachment = TQStringList(),
+ const TQStringList &attendees = TQStringList(),
+ const TQStringList &attachmentMimetypes = TQStringList(),
+ bool inlineAttachment = false );
/** Create a read-only viewer dialog for the supplied incidence. It calls the correct showXXX method*/
- void showIncidence( Incidence * );
+ void showIncidence( Incidence *, const TQDate & );
/** Create an editor for the supplied incidence. It calls the correct editXXX method*/
- bool editIncidence( Incidence *incidence, bool isCounter = false );
+ bool editIncidence( Incidence *incidence, const TQDate &date, bool isCounter = false );
/**
Delete the supplied incidence. It calls the correct deleteXXX method
@param force If true, all recurrences and sub-todos (if applicable) will be
@@ -331,20 +341,29 @@ class KDE_EXPORT CalendarView : public KOrg::CalendarViewBase, public Calendar::
/** create new todo */
void newTodo();
+ void newTodo( ResourceCalendar *res, const TQString &subRes );
/** create new todo, due on date */
- void newTodo( const TQDate &date );
+ void newTodo( ResourceCalendar *res, const TQString &subRes,
+ const TQDate &date );
/** create new todo with a parent todo */
void newSubTodo();
/** create new todo with a parent todo */
void newSubTodo( Todo * );
- void newTodo( const TQString &summary, const TQString &description = TQString::null,
- const TQStringList &attachments = TQStringList(), const TQStringList &attendees = TQStringList(),
- const TQStringList &attachmentMimetypes = TQStringList(), bool inlineAttachment = false );
+ void newTodo( ResourceCalendar *res, const TQString &subRes,
+ const TQString &summary,
+ const TQString &description = TQString::null,
+ const TQStringList &attachments = TQStringList(),
+ const TQStringList &attendees = TQStringList(),
+ const TQStringList &attachmentMimetypes = TQStringList(),
+ bool inlineAttachment = false, bool createTask = false );
void newJournal();
- void newJournal( const TQDate &date );
- void newJournal( const TQString &text, const TQDate &date = TQDate() );
+ void newJournal( ResourceCalendar *res, const TQString &subRes );
+ void newJournal( ResourceCalendar *res, const TQString &subRes,
+ const TQDate &date );
+ void newJournal( ResourceCalendar *res, const TQString &subRes,
+ const TQString &text, const TQDate &date = TQDate() );
void toggleAlarm( Incidence * );
void dissociateOccurrence( Incidence *, const TQDate & );
@@ -379,8 +398,8 @@ class KDE_EXPORT CalendarView : public KOrg::CalendarViewBase, public Calendar::
void changeIncidenceDisplay( Incidence *, int );
void incidenceAdded( Incidence * );
- void incidenceChanged( Incidence *oldEvent, Incidence *newEvent );
- void incidenceChanged( Incidence *oldEvent, Incidence *newEvent, int what );
+ void incidenceChanged( Incidence *oldEvent, Incidence *newEvent,
+ KOGlobals::WhatChanged modification );
void incidenceToBeDeleted( Incidence *incidence );
void incidenceDeleted( Incidence * );
void startMultiModify( const TQString &text );
@@ -434,14 +453,21 @@ class KDE_EXPORT CalendarView : public KOrg::CalendarViewBase, public Calendar::
*/
void appointment_delete();
- /* frees a subtodo from it's relation, update the view */
+ /* frees the selected to-do's children from it's relation, update the view */
void todo_unsub();
- /* Free a subtodo from it's relation, without update the view */
- bool todo_unsub( Todo *todo );
- /** Make all sub-to-dos of todo independents, update the view*/
- bool makeSubTodosIndependents ( );
- /** Make all sub-to-dos of todo independents, not update the view*/
- bool makeSubTodosIndependents ( Todo *todo );
+
+ /* frees an incidence's children from it's relation, without update the view
+ Works with any incidence type, although currently we only pass to-dos
+ */
+ bool incidence_unsub( Incidence *inc );
+
+ /** Make all sub-to-dos of the selected todo independent, update the view */
+ bool makeSubTodosIndependent ( );
+
+ /** Make all children of incidence independent, not update the view
+ Works with any incidence type, although currently we only pass to-dos
+ */
+ bool makeChildrenIndependent( Incidence *inc );
/** Take ownership of selected event. */
void takeOverEvent();
@@ -506,15 +532,13 @@ class KDE_EXPORT CalendarView : public KOrg::CalendarViewBase, public Calendar::
void dialogClosing( Incidence * );
- void processMainViewSelection( Incidence * );
- void processTodoListSelection( Incidence * );
+ void processMainViewSelection( Incidence *incidence, const TQDate &date );
+ void processTodoListSelection( Incidence *incidence, const TQDate &date );
- void processIncidenceSelection( Incidence * );
+ void processIncidenceSelection( Incidence *incidence, const TQDate &date );
void purgeCompleted();
- void slotCalendarChanged();
-
void slotAutoArchivingSettingsModified() { emit autoArchivingSettingsModified(); }
void showErrorMessage( const TQString & );
@@ -525,9 +549,20 @@ class KDE_EXPORT CalendarView : public KOrg::CalendarViewBase, public Calendar::
void resourcesChanged();
+ /**
+ The user clicked on a week number in the date navigator
+
+ Lets select a week or a work week depending on the user's
+ config option.
+ */
+ void selectWeek( const TQDate & );
+
protected slots:
- /** Select a view or adapt the current view to display the specified dates. */
- void showDates( const KCal::DateList & );
+ /** Select a view or adapt the current view to display the specified dates.
+ preferredMonth is useful when the datelist crosses months, if valid,
+ any month-like component should honour this
+ */
+ void showDates( const KCal::DateList &, const TQDate &preferredMonth = TQDate() );
public:
// show a standard warning
@@ -539,7 +574,52 @@ class KDE_EXPORT CalendarView : public KOrg::CalendarViewBase, public Calendar::
*/
void adaptNavigationUnits();
- //Attendee* getYourAttendee( Event *event );
+ /**
+ Returns the date of the selected incidence.
+
+ If the selected incidence is recurring, it will return
+ the date of the selected occurrence
+ */
+ TQDate activeIncidenceDate();
+
+ /**
+ Returns the best guess at the current active date in the view.
+ This has nothing to do with selected incidences, use activeIncidenceDate()
+ for that, for example, agenda supports time selection and incidence selection
+ and they can have diferent dates.
+
+ @param fallbackToToday If guessing doesn't work, some views will prefer
+ today to be returned instead of the first select date in the day matrix,
+ Journal view for example.
+ */
+ TQDate activeDate( bool fallbackToToday = false );
+
+ /**
+ Asks the user if he wants to edit only this occurrence, all
+ occurrences or only future occurrences, and then dissociates
+ the incidence if needed.
+
+ @param inc The recurring incidence that's about to be edited.
+ @param userAction Specifies what the user is doing with the occurrence,
+ like cutting, pasting or editing, it only influences the strings
+ in the message box.
+ @param chosenOption After calling this function, it will hold the user's
+ chosen option.
+ @param itemDate The date of the selected view item
+ @param commitToCalendar If true, mChanger is called and the dissociation
+ is saved to the calendar. If false, it's up to the caller to do that.
+
+ @return A pointer to the incidence that should be edited which is
+ 0 if the user pressed cancel, inc if the user pressed
+ "All Occurrences", or points to a newly created incidence
+ when dissociation is involved in which case the caller
+ is responsible to add it to the calendar and freeing it.
+ **/
+ Incidence* singleOccurrenceOrAll( Incidence *inc,
+ KOGlobals::OccurrenceAction userAction,
+ KOGlobals::WhichOccurrences &chosenOption,
+ const TQDate &itemDate = TQDate(),
+ const bool commitToCalendar = false );
protected:
void setIncidenceChanger( IncidenceChangerBase *changer );
@@ -555,18 +635,33 @@ class KDE_EXPORT CalendarView : public KOrg::CalendarViewBase, public Calendar::
defaults, if invalid values are given) and allow the view to adjust the
type. */
void dateTimesForNewEvent( TQDateTime &startDt, TQDateTime &endDt, bool &allDay );
- KOEventEditor *newEventEditor( const TQDateTime &startDtParam = TQDateTime(),
- const TQDateTime &endDtParam = TQDateTime() , bool allDayParam = false );
+ KOEventEditor *newEventEditor( ResourceCalendar *res, const TQString &subRes,
+ const TQDateTime &startDtParam = TQDateTime(),
+ const TQDateTime &endDtParam = TQDateTime() ,
+ bool allDayParam = false );
private:
void init();
+ /**
+ Returns the incidence that should be sent to clipboard.
+ Usually it's just returns the selected incidence, but, if
+ the incidence is recurring, it will ask the user what he wants to
+ cut/paste and dissociate the incidence if necesssary.
+ **/
+ Incidence *incToSendToClipboard( bool cut );
+
void calendarModified( bool, Calendar * );
// Helper function for purgeCompleted that recursively purges a todo and
// its subitems. If it cannot delete a completed todo (because it has
// uncompleted subitems), notAllPurged is set to true.
bool purgeCompletedSubTodos( Todo* todo, bool &notAllPurged );
+ /** Returns all incidences having inc has their parent (or grand parent, etc.)
+ inc is included in the list too.
+ */
+ void getIncidenceHierarchy( Incidence *inc, Incidence::List &incidences );
+
KOrg::History *mHistory;
TQSplitter *mPanner;
@@ -574,16 +669,18 @@ class KDE_EXPORT CalendarView : public KOrg::CalendarViewBase, public Calendar::
TQWidget *mLeftFrame;
TQWidgetStack *mRightFrame;
+ // This navigator bar is used when in full window month view
+ // It has nothing to do with the date navigator
NavigatorBar *mNavigatorBar;
- DateNavigatorContainer *mDateNavigator;
+ DateNavigatorContainer *mDateNavigatorContainer;
TQPtrList<CalendarViewExtension> mExtensions;
Calendar *mCalendar;
- DateNavigator *mNavigator;
+ DateNavigator *mDateNavigator;
DateChecker *mDateChecker;
KOEventViewer *mEventViewer;
@@ -597,9 +694,9 @@ class KDE_EXPORT CalendarView : public KOrg::CalendarViewBase, public Calendar::
// various housekeeping variables.
bool mModified; // flag indicating if calendar is modified
bool mReadOnly; // flag indicating if calendar is read-only
- TQDate mSaveSingleDate;
Incidence *mSelectedIncidence;
+ TQDate mSaveDate;
KOTodoView *mTodoList;
TQMap<Incidence*,KOIncidenceEditor*> mDialogList;
diff --git a/korganizer/datenavigator.cpp b/korganizer/datenavigator.cpp
index 6f5570a1..edc036ce 100644
--- a/korganizer/datenavigator.cpp
+++ b/korganizer/datenavigator.cpp
@@ -54,11 +54,11 @@ int DateNavigator::datesCount() const
return mSelectedDates.count();
}
-void DateNavigator::selectDates( const DateList& dateList )
+void DateNavigator::selectDates( const DateList &dateList )
{
- if (dateList.count() > 0) {
+ if ( dateList.count() > 0 ) {
mSelectedDates = dateList;
-
+
emitSelected();
}
}
@@ -83,26 +83,33 @@ void DateNavigator::selectDates( int count )
selectDates( mSelectedDates.first(), count );
}
-void DateNavigator::selectDates( const TQDate &d, int count )
+void DateNavigator::selectDates( const TQDate &d, int count, const TQDate &preferredMonth )
{
+ if ( count > MAX_SELECTABLE_DAYS ) {
+ count = MAX_SELECTABLE_DAYS;
+ }
+
DateList dates;
int i;
for( i = 0; i < count; ++i ) {
dates.append( d.addDays( i ) );
}
-
+
mSelectedDates = dates;
-
- emitSelected();
+
+ emitSelected( preferredMonth );
}
-void DateNavigator::selectWeekByDay( int weekDay, const TQDate &d )
+void DateNavigator::selectWeekByDay( int weekDay, const TQDate &d, const TQDate &preferredMonth )
{
int dateCount = mSelectedDates.count();
bool weekStart = ( weekDay == KGlobal::locale()->weekStartDay() );
- if ( weekStart && dateCount == 7 ) selectWeek( d );
- else selectDates( d, dateCount );
+ if ( weekStart && dateCount == 7 ) {
+ selectWeek( d, preferredMonth );
+ } else {
+ selectDates( d, dateCount, preferredMonth );
+ }
}
void DateNavigator::selectWeek()
@@ -110,7 +117,7 @@ void DateNavigator::selectWeek()
selectWeek( mSelectedDates.first() );
}
-void DateNavigator::selectWeek( const TQDate &d )
+void DateNavigator::selectWeek( const TQDate &d, const TQDate &preferredMonth )
{
int dayOfWeek = KOGlobals::self()->calendarSystem()->dayOfWeek( d );
@@ -122,7 +129,7 @@ void DateNavigator::selectWeek( const TQDate &d )
firstDate = firstDate.addDays( -7 );
}
- selectDates( firstDate, 7 );
+ selectDates( firstDate, 7, preferredMonth );
}
void DateNavigator::selectWorkWeek()
@@ -133,7 +140,7 @@ void DateNavigator::selectWorkWeek()
void DateNavigator::selectWorkWeek( const TQDate &d )
{
int weekStart = KGlobal::locale()->weekStartDay();
-
+
int dayOfWeek = KOGlobals::self()->calendarSystem()->dayOfWeek( d );
TQDate currentDate = d.addDays( weekStart - dayOfWeek );
@@ -147,10 +154,10 @@ void DateNavigator::selectWorkWeek( const TQDate &d )
for ( int i = 0; i < 7; ++i ) {
if( (1<< ((i + weekStart + 6) % 7)) & (mask) ) {
- mSelectedDates.append(currentDate.addDays(i));
+ mSelectedDates.append( currentDate.addDays(i) );
}
}
-
+
emitSelected();
}
@@ -160,8 +167,13 @@ void DateNavigator::selectToday()
int dateCount = mSelectedDates.count();
- if ( dateCount == 7 ) selectWeek( d );
- else selectDates( d, dateCount );
+ if ( dateCount == 7 ) {
+ selectWeek( d );
+ } else if ( dateCount == 5 ) {
+ selectWorkWeek( d );
+ } else {
+ selectDates( d, dateCount );
+ }
}
void DateNavigator::selectPreviousYear()
@@ -173,13 +185,14 @@ void DateNavigator::selectPreviousYear()
selectWeekByDay( weekDay, firstSelected );
}
-void DateNavigator::selectPreviousMonth()
+void DateNavigator::selectPreviousMonth( const TQDate &currentMonth,
+ const TQDate &selectionLowerLimit,
+ const TQDate &selectionUpperLimit )
{
- TQDate firstSelected = mSelectedDates.first();
- int weekDay = firstSelected.dayOfWeek();
- firstSelected = KOGlobals::self()->calendarSystem()->addMonths( firstSelected, -1 );
-
- selectWeekByDay( weekDay, firstSelected );
+ shiftMonth( currentMonth,
+ selectionLowerLimit,
+ selectionUpperLimit,
+ -1 );
}
void DateNavigator::selectPreviousWeek()
@@ -201,14 +214,46 @@ void DateNavigator::selectNextWeek()
selectWeekByDay( weekDay, firstSelected );
}
-void DateNavigator::selectNextMonth()
+void DateNavigator::shiftMonth( const TQDate &currentMonth,
+ const TQDate &selectionLowerLimit,
+ const TQDate &selectionUpperLimit,
+ int offset )
{
+ const KCalendarSystem *calSys = KOGlobals::self()->calendarSystem();
+
TQDate firstSelected = mSelectedDates.first();
int weekDay = firstSelected.dayOfWeek();
+ firstSelected = calSys->addMonths( firstSelected, offset );
+
+ /* Don't trust firstSelected to calculate the nextMonth. firstSelected
+ can belong to a month other than currentMonth because KDateNavigator
+ displays 7*6 days. firstSelected should only be used for selection
+ purposes */
+ const TQDate nextMonth = currentMonth.isValid() ?
+ calSys->addMonths( currentMonth, offset ) : firstSelected;
+
+ /* When firstSelected doesn't belong to currentMonth it can happen
+ that the new selection won't be visible on our KDateNavigators
+ so we must adjust it */
+ if ( selectionLowerLimit.isValid() &&
+ firstSelected < selectionLowerLimit ) {
+ firstSelected = selectionLowerLimit;
+ } else if ( selectionUpperLimit.isValid() &&
+ firstSelected > selectionUpperLimit ) {
+ firstSelected = selectionUpperLimit.addDays( -6 );
+ }
- firstSelected = KOGlobals::self()->calendarSystem()->addMonths( firstSelected, 1 );
+ selectWeekByDay( weekDay, firstSelected, nextMonth );
+}
- selectWeekByDay( weekDay, firstSelected );
+void DateNavigator::selectNextMonth( const TQDate &currentMonth,
+ const TQDate &selectionLowerLimit,
+ const TQDate &selectionUpperLimit )
+{
+ shiftMonth( currentMonth,
+ selectionLowerLimit,
+ selectionUpperLimit,
+ 1 );
}
void DateNavigator::selectNextYear()
@@ -240,26 +285,41 @@ void DateNavigator::selectNext()
selectDates( mSelectedDates.first().addDays( offset ), datesCount() );
}
-void DateNavigator::selectMonth(int month)
+void DateNavigator::selectMonth( int month )
{
+ const KCalendarSystem *calSys = KOGlobals::self()->calendarSystem();
+
TQDate firstSelected = mSelectedDates.first();
int weekDay = firstSelected.dayOfWeek();
- const KCalendarSystem *calSys = KOGlobals::self()->calendarSystem();
int day = calSys->day( firstSelected );
- calSys->setYMD( firstSelected, calSys->year(firstSelected), month, 1 );
+ calSys->setYMD( firstSelected, calSys->year( firstSelected ), month, 1 );
int days = calSys->daysInMonth( firstSelected );
// As day we use either the selected date, or if the month has less days
// than that, we use the max day of that month
- if ( day > days ) day = days;
+ if ( day > days ) {
+ day = days;
+ }
+ TQDate requestedMonth;
calSys->setYMD( firstSelected, calSys->year( firstSelected ), month, day );
+ calSys->setYMD( requestedMonth, calSys->year( firstSelected ), month, 1 );
+
+ selectWeekByDay( weekDay, firstSelected, requestedMonth );
+}
+void DateNavigator::selectYear( int year )
+{
+ TQDate firstSelected = mSelectedDates.first();
+ int deltaYear = year - KOGlobals::self()->calendarSystem()->year( firstSelected );
+ firstSelected = KOGlobals::self()->calendarSystem()->addYears( firstSelected, deltaYear );
+
+ int weekDay = firstSelected.dayOfWeek();
selectWeekByDay( weekDay, firstSelected );
}
-void DateNavigator::emitSelected()
+void DateNavigator::emitSelected( const TQDate &preferredMonth )
{
- emit datesSelected( mSelectedDates );
+ emit datesSelected( mSelectedDates, preferredMonth );
}
#include "datenavigator.moc"
diff --git a/korganizer/datenavigator.h b/korganizer/datenavigator.h
index d91bad31..ddb6cf2c 100644
--- a/korganizer/datenavigator.h
+++ b/korganizer/datenavigator.h
@@ -49,38 +49,61 @@ class DateNavigator : public QObject
void selectDate( const TQDate & );
void selectDates( int count );
- void selectDates( const TQDate &, int count );
+ void selectDates( const TQDate &, int count, const TQDate &preferredMonth = TQDate() );
void selectWeek();
- void selectWeek( const TQDate & );
+ void selectWeek( const TQDate &, const TQDate &preferredMonth = TQDate() );
void selectWorkWeek();
void selectWorkWeek( const TQDate & );
- void selectWeekByDay( int weekDay, const TQDate & );
-
+ void selectWeekByDay( int weekDay, const TQDate &, const TQDate &preferredMonth = TQDate() );
+
void selectToday();
-
+
void selectPreviousYear();
- void selectPreviousMonth();
+ void selectPreviousMonth( const TQDate &currentMonth = TQDate(),
+ const TQDate &selectionLowerLimit = TQDate(),
+ const TQDate &selectionUpperLimit = TQDate() );
void selectPreviousWeek();
void selectNextWeek();
- void selectNextMonth();
+ void selectNextMonth( const TQDate &currentMonth = TQDate(),
+ const TQDate &selectionLowerLimit = TQDate(),
+ const TQDate &selectionUpperLimit = TQDate() );
void selectNextYear();
-
+
void selectPrevious();
void selectNext();
- void selectMonth(int month);
-
+ void selectMonth( int month );
+ void selectYear( int year );
+
signals:
- void datesSelected( const KCal::DateList & );
+ /* preferredMonth is useful when the datelist crosses months,
+ if valid, any month-like component should honour it
+ */
+ void datesSelected( const KCal::DateList &, const TQDate &preferredMonth );
protected:
- void emitSelected();
+ void emitSelected( const TQDate &preferredMonth = TQDate() );
private:
+
+ /*
+ Selects next month if offset equals 1, or previous month
+ if offset equals -1.
+ Bigger offsets are accepted.
+ */
+ void shiftMonth( const TQDate &date,
+ const TQDate &selectionLowerLimit,
+ const TQDate &selectionUpperLimit,
+ int offset );
+
KCal::DateList mSelectedDates;
+
+ enum {
+ MAX_SELECTABLE_DAYS = 50
+ };
};
#endif
diff --git a/korganizer/datenavigatorcontainer.cpp b/korganizer/datenavigatorcontainer.cpp
index e3c092fc..ac089294 100644
--- a/korganizer/datenavigatorcontainer.cpp
+++ b/korganizer/datenavigatorcontainer.cpp
@@ -29,6 +29,7 @@
#include "koglobals.h"
#include "navigatorbar.h"
#include "kdatenavigator.h"
+#include "kodaymatrix.h"
#include <kcalendarsystem.h>
#include <kdialog.h>
@@ -79,12 +80,14 @@ void DateNavigatorContainer::connectNavigatorView( KDateNavigator *v )
connect( v, TQT_SIGNAL( goPrevious() ), TQT_SIGNAL( goPrevious() ) );
connect( v, TQT_SIGNAL( goNext() ), TQT_SIGNAL( goNext() ) );
- connect( v, TQT_SIGNAL( goNextMonth() ), TQT_SIGNAL( goNextMonth() ) );
- connect( v, TQT_SIGNAL( goPrevMonth() ), TQT_SIGNAL( goPrevMonth() ) );
- connect( v, TQT_SIGNAL( goNextYear() ), TQT_SIGNAL( goNextYear() ) );
- connect( v, TQT_SIGNAL( goPrevYear() ), TQT_SIGNAL( goPrevYear() ) );
+ connect( v, TQT_SIGNAL( nextYearClicked() ), TQT_SIGNAL( nextYearClicked() ) );
+ connect( v, TQT_SIGNAL( prevYearClicked() ), TQT_SIGNAL( prevYearClicked() ) );
- connect( v, TQT_SIGNAL( goMonth( int ) ), TQT_SIGNAL( goMonth( int ) ) );
+ connect( v, TQT_SIGNAL( prevMonthClicked() ), this, TQT_SLOT( goPrevMonth() ) );
+ connect( v, TQT_SIGNAL( nextMonthClicked() ), this, TQT_SLOT( goNextMonth() ) );
+
+ connect( v, TQT_SIGNAL( monthSelected( int ) ), TQT_SIGNAL( monthSelected( int ) ) );
+ connect( v, TQT_SIGNAL( yearSelected( int ) ), TQT_SIGNAL( yearSelected( int ) ) );
}
void DateNavigatorContainer::setCalendar( Calendar *cal )
@@ -118,12 +121,21 @@ void DateNavigatorContainer::updateToday()
}
}
+void DateNavigatorContainer::setUpdateNeeded()
+{
+ mNavigatorView->setUpdateNeeded();
+ KDateNavigator *n;
+ for ( n = mExtraViews.first(); n; n = mExtraViews.next() ) {
+ n->setUpdateNeeded();
+ }
+}
+
void DateNavigatorContainer::updateView()
{
mNavigatorView->updateView();
KDateNavigator *n;
- for( n = mExtraViews.first(); n; n = mExtraViews.next() ) {
- n->updateView();
+ for ( n = mExtraViews.first(); n; n = mExtraViews.next() ) {
+ n->setUpdateNeeded();
}
}
@@ -136,7 +148,7 @@ void DateNavigatorContainer::updateConfig()
}
}
-void DateNavigatorContainer::selectDates( const DateList &dateList )
+void DateNavigatorContainer::selectDates( const DateList &dateList, const TQDate &preferredMonth )
{
if ( !dateList.isEmpty() ) {
TQDate start( dateList.first() );
@@ -151,11 +163,24 @@ void DateNavigatorContainer::selectDates( const DateList &dateList )
navlast = mNavigatorView->endDate();
navsecond = navfirst;
}
+
+ const KCalendarSystem *calSys = KOGlobals::self()->calendarSystem();
+
+ // If the datelist crosses months we won't know which month to show
+ // so we read what's in preferredMonth
+ const bool changingMonth = ( preferredMonth.isValid() &&
+ calSys->month( mNavigatorView->month() ) != calSys->month( preferredMonth ) );
+
if ( start < navfirst // <- start should always be visible
// end is not visible and we have a spare month at the beginning:
- || ( end > navlast && start >= navsecond ) ) {
- // Change the shown months so that the beginning of the date list is visible
- setBaseDates( start );
+ || ( end > navlast && start >= navsecond )
+ || changingMonth ) {
+
+ if ( preferredMonth.isValid() ) {
+ setBaseDates( preferredMonth );
+ } else {
+ setBaseDates( start );
+ }
}
mNavigatorView->selectDates( dateList );
@@ -202,7 +227,9 @@ void DateNavigatorContainer::resizeAllContents()
if ( horizontalCount != mHorizontalCount ||
verticalCount != mVerticalCount ) {
uint count = horizontalCount * verticalCount;
- if ( count == 0 ) return;
+ if ( count == 0 ) {
+ return;
+ }
while ( count > ( mExtraViews.count() + 1 ) ) {
KDateNavigator *n = new KDateNavigator( this );
@@ -228,22 +255,30 @@ void DateNavigatorContainer::resizeAllContents()
int width = (size().width() - margin*2) / horizontalCount;
NavigatorBar *bar = mNavigatorView->navigatorBar();
- if ( horizontalCount > 1 ) bar->showButtons( true, false );
- else bar->showButtons( true, true );
+ if ( horizontalCount > 1 ) {
+ bar->showButtons( true, false );
+ } else {
+ bar->showButtons( true, true );
+ }
mNavigatorView->setGeometry(
( ( (KOGlobals::self()->reverseLayout())?(horizontalCount-1):0) * width ) + margin,
margin, width, height );
+
for( uint i = 0; i < mExtraViews.count(); ++i ) {
int x = ( i + 1 ) % horizontalCount;
int y = ( i + 1 ) / horizontalCount;
KDateNavigator *view = mExtraViews.at( i );
bar = view->navigatorBar();
- if ( y > 0 ) bar->showButtons( false, false );
- else {
- if ( x + 1 == horizontalCount ) bar->showButtons( false, true );
- else bar->showButtons( false, false );
+ if ( y > 0 ) {
+ bar->showButtons( false, false );
+ } else {
+ if ( x + 1 == horizontalCount ) {
+ bar->showButtons( false, true );
+ } else {
+ bar->showButtons( false, false );
+ }
}
view->setGeometry(
( ( (KOGlobals::self()->reverseLayout())?(horizontalCount-1-x):x) * width ) + margin,
@@ -263,4 +298,41 @@ TQSize DateNavigatorContainer::sizeHint() const
return mNavigatorView->sizeHint() + TQSize( margin, margin );
}
+void DateNavigatorContainer::goNextMonth()
+{
+ const QPair<TQDate,TQDate> p = dateLimits( 1 );
+
+ emit nextMonthClicked( mNavigatorView->month(),
+ p.first,
+ p.second);
+}
+
+void DateNavigatorContainer::goPrevMonth()
+{
+ const QPair<TQDate,TQDate> p = dateLimits( -1 );
+
+ emit prevMonthClicked( mNavigatorView->month(),
+ p.first,
+ p.second );
+}
+
+QPair<TQDate,TQDate> DateNavigatorContainer::dateLimits( int offset )
+{
+ const KCalendarSystem *calSys = KOGlobals::self()->calendarSystem();
+ TQDate firstMonth, lastMonth;
+ if ( mExtraViews.isEmpty() ) {
+ lastMonth = mNavigatorView->month();
+ } else {
+ lastMonth = mExtraViews.last()->month();
+ }
+
+ firstMonth = calSys->addMonths( mNavigatorView->month(), offset );
+ lastMonth = calSys->addMonths( lastMonth, offset );
+
+ QPair<TQDate,TQDate> firstMonthBoundary = KODayMatrix::matrixLimits( firstMonth );
+ QPair<TQDate,TQDate> lastMonthBoundary = KODayMatrix::matrixLimits( lastMonth );
+
+ return qMakePair( firstMonthBoundary.first, lastMonthBoundary.second );
+}
+
#include "datenavigatorcontainer.moc"
diff --git a/korganizer/datenavigatorcontainer.h b/korganizer/datenavigatorcontainer.h
index 2facad30..e30f19b4 100644
--- a/korganizer/datenavigatorcontainer.h
+++ b/korganizer/datenavigatorcontainer.h
@@ -43,29 +43,53 @@ class DateNavigatorContainer: public QFrame
TQSize minimumSizeHint() const;
TQSize sizeHint() const;
-
+ void setUpdateNeeded();
public slots:
- void selectDates( const KCal::DateList & );
+ /**
+ preferredMonth is useful when the datelist crosses months, if different
+ from -1, it has the month that the kdatenavigator should show in case
+ of ambiguity
+ */
+ void selectDates( const KCal::DateList &, const TQDate &preferredMonth = TQDate() );
void updateView();
void updateConfig();
void updateDayMatrix();
void updateToday();
+ void goPrevMonth();
+ void goNextMonth();
+
signals:
void datesSelected( const KCal::DateList & );
void incidenceDropped( Incidence *, const TQDate & );
void incidenceDroppedMove( Incidence *, const TQDate & );
- void weekClicked( const TQDate &);
+ void weekClicked( const TQDate & );
void goPrevious();
void goNext();
- void goNextMonth();
- void goPrevMonth();
- void goNextYear();
- void goPrevYear();
+ void nextYearClicked();
+ void prevYearClicked();
- void goMonth( int month );
+ /** Signals that the previous month button has been clicked.
+
+ @param currentMonth The month displayed on the first KDateNavigator.
+ DateNavigator doesn't know anything abouts months, it just has
+ a list of selected dates, so we must send this.
+ @param selectionLowerLimit The first date of the first KDateNavigator.
+ @param selectionUpperLimit The last date of the last KDateNavigator.
+ */
+ void prevMonthClicked( const TQDate &currentMonth,
+ const TQDate &selectionLowerLimit,
+ const TQDate &selectionUpperLimit );
+
+ void nextMonthClicked( const TQDate &currentMonth,
+ const TQDate &selectionLowerLimit,
+ const TQDate &selectionUpperLimit );
+
+ void monthSelected( int month );
+
+ void yearSelected( int year );
protected:
void resizeEvent( TQResizeEvent * );
@@ -79,6 +103,15 @@ class DateNavigatorContainer: public QFrame
void resizeAllContents();
private:
+ /* Returns the first day of the first KDateNavigator, and the last day
+ of the last KDateNavigator.
+
+ @param monthOffset If you have two KDateNavigators displaying January and February
+ and want to know the boundaries of, for e.g. displaying February and March,
+ use monthOffset = 1.
+ */
+ QPair<TQDate,TQDate> dateLimits( int monthOffset = 0 );
+
KDateNavigator *mNavigatorView;
KCal::Calendar *mCalendar;
diff --git a/korganizer/dcopcalendar.desktop b/korganizer/dcopcalendar.desktop
index df5c098a..ac1ccf4e 100644
--- a/korganizer/dcopcalendar.desktop
+++ b/korganizer/dcopcalendar.desktop
@@ -29,7 +29,6 @@ Comment[hu]=Határidőnapló DCOP-felülettel
Comment[is]=Skipuleggjari með DCOP viðmóti
Comment[it]=Organizer con un'interfaccia DCOP
Comment[ja]=DCOP インターフェースを持つオーガナイザ
-Comment[ka]=ორგანიზატორი DCOP ინტერფეისით
Comment[kk]=DCOP интерфейсті Ұйымдастырғыш
Comment[km]=កម្មវិធី​រៀបចំ​ដែល​មាន​ចំណុច​ប្រទាក់ DCOP
Comment[lt]=Tvarkyklė su DCOP sąsaja
diff --git a/korganizer/eventarchiver.cpp b/korganizer/eventarchiver.cpp
index b5a9c0c9..c4adbf82 100644
--- a/korganizer/eventarchiver.cpp
+++ b/korganizer/eventarchiver.cpp
@@ -70,14 +70,15 @@ void EventArchiver::runAuto( Calendar* calendar, TQWidget* widget, bool withGUI
run( calendar, limitDate, widget, withGUI, false );
}
-void EventArchiver::run( Calendar* calendar, const TQDate& limitDate, TQWidget* widget, bool withGUI, bool errorIfNone )
+void EventArchiver::run( Calendar* calendar, const TQDate& limitDate, TQWidget* widget, bool withGUI,
+ bool errorIfNone )
{
// We need to use rawEvents, otherwise events hidden by filters will not be archived.
Incidence::List incidences;
Event::List events;
Todo::List todos;
Journal::List journals;
-
+
if ( KOPrefs::instance()->mArchiveEvents ) {
events = calendar->rawEvents(
TQDate( 1769, 12, 1 ),
@@ -89,21 +90,37 @@ void EventArchiver::run( Calendar* calendar, const TQDate& limitDate, TQWidget*
Todo::List t = calendar->rawTodos();
Todo::List::ConstIterator it;
for( it = t.begin(); it != t.end(); ++it ) {
- if ( (*it) && ( (*it)->isCompleted() ) && ( (*it)->completed().date() < limitDate ) ) {
+ const bool todoComplete = (*it) &&
+ (*it)->isCompleted() &&
+ ( (*it)->completed().date() < limitDate );
+
+ if ( todoComplete && !isSubTreeComplete( *it, limitDate ) ) {
+ // The to-do is complete but some sub-todos are not.
+ KMessageBox::information(
+ widget,
+ i18n( "Unable to archive to-do \"%1\" because at least one of its "
+ "sub-to-dos does not meet the archival requirements." ).arg( (*it)->summary() ),
+ i18n( "Archive To-do" ),
+ "UncompletedChildrenArchiveTodos" );
+ } else if ( todoComplete ) {
todos.append( *it );
}
}
}
-
+
incidences = Calendar::mergeIncidenceList( events, todos, journals );
-
- kdDebug(5850) << "EventArchiver: archiving incidences before " << limitDate << " -> " << incidences.count() << " incidences found." << endl;
+
+ kdDebug(5850) << "EventArchiver: archiving incidences before " << limitDate << " -> "
+ << incidences.count() << " incidences found." << endl;
if ( incidences.isEmpty() ) {
- if ( withGUI && errorIfNone )
- KMessageBox::information( widget, i18n("There are no items before %1")
- .arg(KGlobal::locale()->formatDate(limitDate)),
- "ArchiverNoIncidences" );
+ if ( withGUI && errorIfNone ) {
+ KMessageBox::information(
+ widget,
+ i18n( "There are no incidences available to archive before the specified cut-off date %1. "
+ "Archiving will not be performed." ).arg( KGlobal::locale()->formatDate( limitDate ) ),
+ "ArchiverNoIncidences" );
+ }
return;
}
@@ -222,4 +239,35 @@ void EventArchiver::archiveIncidences( Calendar* calendar, const TQDate& /*limit
emit eventsDeleted();
}
+bool EventArchiver::isSubTreeComplete( const Todo *todo, const TQDate &limitDate,
+ TQStringList checkedUids ) const
+{
+ if ( !todo || !todo->isCompleted() || todo->completed().date() >= limitDate ) {
+ return false;
+ }
+
+ // This QList is only to prevent infinit recursion
+ if ( checkedUids.contains( todo->uid() ) ) {
+ // Probably will never happen, calendar.cpp checks for this
+ kdWarning() << "To-do hierarchy loop detected!";
+ return false;
+ }
+
+ checkedUids.append( todo->uid() );
+
+ Incidence::List::ConstIterator it;
+ const Incidence::List relations = todo->relations();
+
+ for( it = relations.begin(); it != relations.end(); ++it ) {
+ if ( (*it)->type() == "Todo" ) {
+ const Todo *t = static_cast<const Todo*>( *it );
+ if ( !isSubTreeComplete( t, limitDate, checkedUids ) ) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
#include "eventarchiver.moc"
diff --git a/korganizer/eventarchiver.h b/korganizer/eventarchiver.h
index 4d5a8544..01897b7e 100644
--- a/korganizer/eventarchiver.h
+++ b/korganizer/eventarchiver.h
@@ -77,8 +77,20 @@ class EventArchiver : public QObject
private:
void run( Calendar* calendar, const TQDate& limitDate, TQWidget* widget, bool withGUI, bool errorIfNone );
- void deleteIncidences( Calendar* calendar, const TQDate& limitDate, TQWidget* widget, const Incidence::List& incidences, bool withGUI );
- void archiveIncidences( Calendar* calendar, const TQDate& limitDate, TQWidget* widget, const Incidence::List& incidences, bool withGUI );
+ void deleteIncidences( Calendar* calendar, const TQDate& limitDate, TQWidget* widget,
+ const Incidence::List& incidences, bool withGUI );
+ void archiveIncidences( Calendar* calendar, const TQDate& limitDate, TQWidget* widget,
+ const Incidence::List& incidences, bool withGUI );
+
+ /**
+ * Checks if all to-dos under @p todo and including @p todo were completed before @p limitDate.
+ * If not, we can't archive this to-do.
+ * @param todo root of the sub-tree we are checking
+ * @param limitDate
+ * @param checkedUids used internaly to prevent infinit recursion due to invalid calendar files
+ */
+ bool isSubTreeComplete( const Todo *todo, const TQDate &limitDate,
+ TQStringList checkedUids = TQStringList() ) const;
};
#endif /* EVENTARCHIVER_H */
diff --git a/korganizer/exportwebdialog.cpp b/korganizer/exportwebdialog.cpp
index c926ad05..869c5b96 100644
--- a/korganizer/exportwebdialog.cpp
+++ b/korganizer/exportwebdialog.cpp
@@ -85,6 +85,7 @@ ExportWebDialog::ExportWebDialog( HTMLExportSettings *settings, TQWidget *parent
connect( this, TQT_SIGNAL( cancelClicked() ), TQT_SLOT( reject() ) );
readConfig();
+ updateState();
}
ExportWebDialog::~ExportWebDialog()
@@ -139,16 +140,18 @@ void ExportWebDialog::setupGeneralPage()
mGeneralPage = addPage( i18n("General") );
TQVBoxLayout *topLayout = new TQVBoxLayout(mGeneralPage, 10);
- TQGroupBox *rangeGroup = new TQHGroupBox( i18n("Date Range"), mGeneralPage );
- topLayout->addWidget( rangeGroup );
- addWidDate( mSettings->dateStartItem(), rangeGroup );
- addWidDate( mSettings->dateEndItem(), rangeGroup );
+ mDateRangeBox = new TQHGroupBox( i18n("Date Range"), mGeneralPage );
+ topLayout->addWidget( mDateRangeBox );
+ addWidDate( mSettings->dateStartItem(), mDateRangeBox );
+ addWidDate( mSettings->dateEndItem(), mDateRangeBox );
TQButtonGroup *typeGroup = new TQVButtonGroup( i18n("View Type"), mGeneralPage );
topLayout->addWidget( typeGroup );
// addWidBool( mSettings->weekViewItem(), typeGroup );
- addWidBool( mSettings->monthViewItem(), typeGroup );
- addWidBool( mSettings->eventViewItem(), typeGroup );
+ mMonthViewCheckBox = addWidBool( mSettings->monthViewItem(), typeGroup )->checkBox();
+ connect( mMonthViewCheckBox, TQT_SIGNAL(toggled(bool)), TQT_SLOT(updateState()) );
+ mEventListCheckBox = addWidBool( mSettings->eventViewItem(), typeGroup )->checkBox();
+ connect( mEventListCheckBox, TQT_SIGNAL(toggled(bool)), TQT_SLOT(updateState()) );
addWidBool( mSettings->todoViewItem(), typeGroup );
// addWidBool( mSettings->journalViewItem(), typeGroup );
// addWidBool( mSettings->freeBusyViewItem(), typeGroup );
@@ -255,3 +258,11 @@ void ExportWebDialog::setupAdvancedPage()
topLayout->addStretch(1);
}
*/
+
+void ExportWebDialog::updateState()
+{
+ const bool exportEvents = mMonthViewCheckBox->isChecked() || mEventListCheckBox->isChecked();
+ mDateRangeBox->setEnabled( exportEvents );
+ mEventPage->setEnabled( exportEvents );
+}
+
diff --git a/korganizer/exportwebdialog.h b/korganizer/exportwebdialog.h
index 4d2dcd39..27a0a986 100644
--- a/korganizer/exportwebdialog.h
+++ b/korganizer/exportwebdialog.h
@@ -27,6 +27,7 @@
#include <libkdepim/kprefsdialog.h>
class HTMLExportSettings;
+class TQGroupBox;
using namespace KCal;
@@ -70,6 +71,9 @@ class ExportWebDialog : public KDialogBase, public KPrefsWidManager
protected:
virtual void usrReadConfig() {}
virtual void usrWriteConfig() {}
+
+ private slots:
+ void updateState();
private:
HTMLExportSettings* mSettings;
@@ -79,6 +83,10 @@ class ExportWebDialog : public KDialogBase, public KPrefsWidManager
// TQFrame *mJournalPage;
// TQFrame *mFreeBusyPage;
// TQFrame *mAdvancedPage;
+
+ TQCheckBox *mMonthViewCheckBox;
+ TQCheckBox *mEventListCheckBox;
+ TQGroupBox *mDateRangeBox;
};
#endif // _EXPORTWEBDIALOG_H
diff --git a/korganizer/freebusymanager.cpp b/korganizer/freebusymanager.cpp
index 81b65a3b..65f945ba 100644
--- a/korganizer/freebusymanager.cpp
+++ b/korganizer/freebusymanager.cpp
@@ -39,6 +39,8 @@
#include "koprefs.h"
#include "mailscheduler.h"
+#include "actionmanager.h"
+#include "korganizer.h"
#include <libkcal/incidencebase.h>
#include <libkcal/attendee.h>
@@ -76,6 +78,10 @@ FreeBusyDownloadJob::FreeBusyDownloadJob( const TQString &email, const KURL &url
: TQObject( manager, name ), mManager( manager ), mEmail( email )
{
KIO::TransferJob *job = KIO::get( url, false, false );
+ //pass the mainwindow to the job so any prompts are active
+ KOrg::MainWindow *korg = ActionManager::findInstance( KURL() );
+ job->setWindow( korg->topLevelWidget() );
+
connect( job, TQT_SIGNAL( result( KIO::Job * ) ),
TQT_SLOT( slotResult( KIO::Job * ) ) );
connect( job, TQT_SIGNAL( data( KIO::Job *, const TQByteArray & ) ),
@@ -224,7 +230,7 @@ void FreeBusyManager::publishFreeBusy()
// Already uploading? Skip this one then.
if ( mUploadingFreeBusy )
return;
- KURL targetURL ( KOPrefs::instance()->freeBusyPublishUrl() );
+ KURL targetURL( KOPrefs::instance()->freeBusyPublishUrl() );
if ( targetURL.isEmpty() ) {
KMessageBox::sorry( 0,
i18n( "<qt>No URL configured for uploading your free/busy list. Please "
@@ -329,6 +335,10 @@ void FreeBusyManager::publishFreeBusy()
true /*overwrite*/,
false /*don't resume*/,
false /*don't show progress info*/ );
+ //pass the mainwindow to the job so any prompts are active
+ KOrg::MainWindow *korg = ActionManager::findInstance( KURL() );
+ job->setWindow( korg->topLevelWidget() );
+
connect( job, TQT_SIGNAL( result( KIO::Job * ) ),
TQT_SLOT( slotUploadFreeBusyResult( KIO::Job * ) ) );
}
@@ -386,11 +396,10 @@ bool FreeBusyManager::processRetrieveQueue()
KURL sourceURL = freeBusyUrl( email );
- DEBUG_5850 << "FreeBusyManager::processRetrieveQueue(): url: " << sourceURL
- << endl;
+ kdDebug(5850) << "FreeBusyManager::processRetrieveQueue(): url: " << sourceURL << endl;
if ( !sourceURL.isValid() ) {
- DEBUG_5850 << "Invalid FB URL\n";
+ kdDebug(5850) << "Invalid FB URL\n";
slotFreeBusyDownloadError( email );
return false;
}
@@ -429,6 +438,43 @@ void FreeBusyManager::cancelRetrieval()
mRetrieveQueue.clear();
}
+KURL replaceVariablesURL( const KURL &url, const TQString &email )
+{
+ TQString emailName, emailHost;
+ int emailpos = email.find( '@' );
+ if( emailpos >= 0 ) {
+ emailName = email.left( emailpos );
+ emailHost = email.mid( emailpos + 1 );
+ }
+
+ TQString saveStr = url.path();
+ saveStr.replace( TQRegExp( "%[Ee][Mm][Aa][Ii][Ll]%" ), email );
+ saveStr.replace( TQRegExp( "%[Nn][Aa][Mm][Ee]%" ), emailName );
+ saveStr.replace( TQRegExp( "%[Ss][Ee][Rr][Vv][Ee][Rr]%" ), emailHost );
+
+ KURL retUrl( url );
+ retUrl.setPath( saveStr );
+ return retUrl;
+}
+
+bool fbExists( const KURL &url )
+{
+ // We need this function because using KIO::NetAccess::exists()
+ // is useless for the http and https protocols. And getting back
+ // arbitrary data is also useless because a server can respond back
+ // with a "no such document" page. So we need smart checking.
+
+ KIO::Job *job = KIO::get( url, false, false );
+ TQByteArray data;
+ if ( KIO::NetAccess::synchronousRun( job, 0, &data ) ) {
+ TQString dataStr ( data );
+ if ( dataStr.contains( "BEGIN:VCALENDAR" ) ) {
+ return true;
+ }
+ }
+ return false;
+}
+
KURL FreeBusyManager::freeBusyUrl( const TQString &email )
{
DEBUG_5850 << "FreeBusyManager::freeBusyUrl(): " << email << endl;
@@ -440,9 +486,15 @@ KURL FreeBusyManager::freeBusyUrl( const TQString &email )
cfg.setGroup( email );
TQString url = cfg.readEntry( "url" );
if ( !url.isEmpty() ) {
- DEBUG_5850 << "found cached url: " << url << endl;
- return KURL( url );
+ kdDebug(5850) << "found cached url: " << url << endl;
+ KURL cachedURL( url );
+ if ( KOPrefs::instance()->thatIsMe( email ) ) {
+ cachedURL.setUser( KOPrefs::instance()->mFreeBusyRetrieveUser );
+ cachedURL.setPass( KOPrefs::instance()->mFreeBusyRetrievePassword );
+ }
+ return replaceVariablesURL( cachedURL, email );
}
+
// Try with the url configurated by preferred email in kaddressbook
KABC::Addressee::List list= KABC::StdAddressBook::self( true )->findByEmail( email );
KABC::Addressee::List::Iterator it;
@@ -450,14 +502,14 @@ KURL FreeBusyManager::freeBusyUrl( const TQString &email )
for ( it = list.begin(); it != list.end(); ++it ) {
pref = (*it).preferredEmail();
if ( !pref.isEmpty() && pref != email ) {
- kdDebug( 5850 ) << "FreeBusyManager::freeBusyUrl():" <<
- "Preferred email of " << email << " is " << pref << endl;
+ kdDebug(5850) << "FreeBusyManager::freeBusyUrl():"
+ << "Preferred email of " << email << " is " << pref << endl;
cfg.setGroup( pref );
url = cfg.readEntry ( "url" );
if ( !url.isEmpty() ) {
- kdDebug( 5850 ) << "FreeBusyManager::freeBusyUrl():" <<
- "Taken url from preferred email:" << url << endl;
- return KURL( url );
+ kdDebug(5850) << "FreeBusyManager::freeBusyUrl():"
+ << "Taken url from preferred email:" << url << endl;
+ return replaceVariablesURL( KURL( url ), email );
}
}
}
@@ -487,54 +539,81 @@ KURL FreeBusyManager::freeBusyUrl( const TQString &email )
// Don't try to fetch free/busy data for users not on the specified servers
// This tests if the hostnames match, or one is a subset of the other
const TQString hostDomain = sourceURL.host();
- if ( hostDomain != emailHost && !hostDomain.endsWith( '.' + emailHost )
- && !emailHost.endsWith( '.' + hostDomain ) ) {
+ if ( hostDomain != emailHost &&
+ !hostDomain.endsWith( '.' + emailHost ) &&
+ !emailHost.endsWith( '.' + hostDomain ) ) {
// Host names do not match
- DEBUG_5850 << "Host '" << sourceURL.host() << "' doesn't match email '"
- << email << '\'' << endl;
+ kdDebug(5850) << "Host '" << sourceURL.host() << "' doesn't match email '" << email << endl;
return KURL();
}
}
- // This should work with anything thrown at it, not just Kolab
- // Notice that Kolab URLs are just entered as the base address, e.g. http://server.com/mykolab/
- // This means that if the trailing slash is not entered, we can treat this as a custom, non-Kolab URL!
- // In that case, just pass it on through with substitution for %u and %d
- // TODO: May want an explicit configuration option in kogroupwareprefspage.ui for this
- if ((sourceURL.url().endsWith("/", true) == false) || (sourceURL.url().contains("%25u", true)) || (sourceURL.url().contains("%25d", true))) {
- // A generic URL, substitute %u and %d
- sourceURL = sourceURL.url().replace("%25u", emailName, true);
- sourceURL = sourceURL.url().replace("%25d", emailHost, true);
- sourceURL.setUser( KOPrefs::instance()->mFreeBusyRetrieveUser );
- sourceURL.setPass( KOPrefs::instance()->mFreeBusyRetrievePassword );
- return sourceURL;
+ if ( sourceURL.url().contains( TQRegExp( "\\.[xiv]fb$" ) ) ) { // user specified a fullpath
+ // do variable string replacements to the URL (MS Outlook style)
+ KURL fullpathURL = replaceVariablesURL( sourceURL, email );
+
+ // This should work with anything thrown at it, not just Kolab
+ // Notice that Kolab URLs are just entered as the base address, e.g. http://server.com/mykolab/
+ // This means that if the trailing slash is not entered, we can treat this as a custom, non-Kolab URL!
+ // In that case, just pass it on through with substitution for %u and %d
+ // TODO: May want an explicit configuration option in kogroupwareprefspage.ui for this
+ if ((fullpathURL.url().endsWith("/", true) == false) || (fullpathURL.url().contains("%25u", true)) || (fullpathURL.url().contains("%25d", true))) {
+ // A generic URL, substitute %u and %d
+ fullpathURL = fullpathURL.url().replace("%25u", emailName, true);
+ fullpathURL = fullpathURL.url().replace("%25d", emailHost, true);
+ }
+ else {
+ // This is (probably) a Kolab URL!
+ }
+
+ // set the User and Password part of the URL
+ fullpathURL.setUser( KOPrefs::instance()->mFreeBusyRetrieveUser );
+ fullpathURL.setPass( KOPrefs::instance()->mFreeBusyRetrievePassword );
+
+ // no need to cache this URL as this is pretty fast to get from the config value.
+
+ // return the fullpath URL
+ return fullpathURL;
}
- else {
- // This is (probably) a Kolab URL!
- DEBUG_5850 << "Server FreeBusy url: " << sourceURL << endl;
- if ( KOPrefs::instance()->mFreeBusyFullDomainRetrieval )
- sourceURL.setFileName( email + ".ifb" );
- else
- sourceURL.setFileName( emailName + ".ifb" );
- sourceURL.setUser( KOPrefs::instance()->mFreeBusyRetrieveUser );
- sourceURL.setPass( KOPrefs::instance()->mFreeBusyRetrievePassword );
-
- DEBUG_5850 << "Results in generated: " << sourceURL << endl;
- return sourceURL;
+
+ // else we search for a fb file in the specified URL with known possible extensions
+
+ TQStringList extensions;
+ extensions << "xfb" << "ifb" << "vfb";
+ TQStringList::ConstIterator ext;
+ for ( ext = extensions.constBegin(); ext != extensions.constEnd(); ++ext ) {
+ // build a url for this extension
+ sourceURL = KOPrefs::instance()->mFreeBusyRetrieveUrl;
+ KURL dirURL = replaceVariablesURL( sourceURL, email );
+ if ( KOPrefs::instance()->mFreeBusyFullDomainRetrieval ) {
+ dirURL.addPath( email + '.' + (*ext) );
+ } else {
+ dirURL.addPath( emailName + '.' + (*ext ) );
+ }
+ dirURL.setUser( KOPrefs::instance()->mFreeBusyRetrieveUser );
+ dirURL.setPass( KOPrefs::instance()->mFreeBusyRetrievePassword );
+ if ( fbExists( dirURL ) ) {
+ // write the URL to the cache
+ cfg.setGroup( email );
+ cfg.writeEntry( "url", dirURL.prettyURL() ); // prettyURL() does not write user nor password
+ return dirURL;
+ }
}
+
+ return KURL();
}
KCal::FreeBusy *FreeBusyManager::iCalToFreeBusy( const TQCString &data )
{
- DEBUG_5850 << "FreeBusyManager::iCalToFreeBusy()" << endl;
- DEBUG_5850 << data << endl;
+ kdDebug(5850) << "FreeBusyManager::iCalToFreeBusy()" << endl;
+ kdDebug(5850) << data << endl;
TQString freeBusyVCal = TQString::fromUtf8( data );
KCal::FreeBusy *fb = mFormat.parseFreeBusy( freeBusyVCal );
if ( !fb ) {
- DEBUG_5850 << "FreeBusyManager::iCalToFreeBusy(): Error parsing free/busy"
+ kdDebug(5850) << "FreeBusyManager::iCalToFreeBusy(): Error parsing free/busy"
<< endl;
- DEBUG_5850 << freeBusyVCal << endl;
+ kdDebug(5850) << freeBusyVCal << endl;
}
return fb;
}
@@ -553,7 +632,7 @@ FreeBusy *FreeBusyManager::loadFreeBusy( const TQString &email )
TQFile f( fbd + "/" + email + ".ifb" );
if ( !f.exists() ) {
DEBUG_5850 << "FreeBusyManager::loadFreeBusy() " << f.name()
- << " doesn't exist." << endl;
+ << " doesn't exist." << endl;
return 0;
}
diff --git a/korganizer/freebusymanager.h b/korganizer/freebusymanager.h
index a91d9f36..a6f4f6ce 100644
--- a/korganizer/freebusymanager.h
+++ b/korganizer/freebusymanager.h
@@ -117,7 +117,7 @@ class FreeBusyManager : public TQObject, public KCal::FreeBusyCache
KURL freeBusyUrl( const TQString &email );
/**
- Return directory used for stroing free/busy information.
+ Return directory used for storing free/busy information.
*/
TQString freeBusyDir();
@@ -173,7 +173,6 @@ class FreeBusyManager : public TQObject, public KCal::FreeBusyCache
int mTimerID;
bool mUploadingFreeBusy;
bool mBrokenUrl;
-
};
#endif
diff --git a/korganizer/importdialog.cpp b/korganizer/importdialog.cpp
index f1181225..5f4dce6a 100644
--- a/korganizer/importdialog.cpp
+++ b/korganizer/importdialog.cpp
@@ -37,15 +37,15 @@
using namespace KCal;
-ImportDialog::ImportDialog( const KURL &url, TQWidget *parent )
- : KDialogBase( Plain, i18n("Import Calendar"), Ok | Cancel, Ok, parent,
+ImportDialog::ImportDialog( const KURL &url, TQWidget *parent, bool isPart )
+ : KDialogBase( Plain, i18n("Import Calendar/Event"), Ok | Cancel, Ok, parent,
0, true, true ),
mUrl( url )
{
TQFrame *topFrame = plainPage();
TQVBoxLayout *topLayout = new TQVBoxLayout( topFrame, 0, spacingHint() );
- TQString txt = i18n("Import calendar at '%1' into KOrganizer.")
+ TQString txt = i18n("Import calendar/event at '%1' into KOrganizer.")
.arg( mUrl.prettyURL() );
topLayout->addWidget( new TQLabel( txt, topFrame ) );
@@ -59,7 +59,7 @@ ImportDialog::ImportDialog( const KURL &url, TQWidget *parent )
mMergeButton = new TQRadioButton( i18n("Merge into existing calendar"),
radioBox );
- mOpenButton = new TQRadioButton( i18n("Open in separate window"), radioBox );
+ mOpenButton = isPart ? 0 : new TQRadioButton( i18n("Open in separate window"), radioBox );
mAddButton->setChecked( true );
}
@@ -77,7 +77,7 @@ void ImportDialog::slotOk()
} else if ( mMergeButton->isChecked() ) {
// emit a signal to action manager to merge mUrl into the current calendar
emit openURL( mUrl, true );
- } else if ( mOpenButton->isChecked() ) {
+ } else if ( mOpenButton && mOpenButton->isChecked() ) {
// emit a signal to the action manager to open mUrl in a separate window
emit newWindow( mUrl );
} else {
diff --git a/korganizer/importdialog.h b/korganizer/importdialog.h
index ae92ae0b..75d5cb1a 100644
--- a/korganizer/importdialog.h
+++ b/korganizer/importdialog.h
@@ -36,7 +36,7 @@ class ImportDialog : public KDialogBase
{
Q_OBJECT
public:
- ImportDialog( const KURL &url, TQWidget *parent );
+ ImportDialog( const KURL &url, TQWidget *parent, bool isPart );
~ImportDialog();
public slots:
diff --git a/korganizer/incidencechanger.cpp b/korganizer/incidencechanger.cpp
index 46be25ba..1c41c5cd 100644
--- a/korganizer/incidencechanger.cpp
+++ b/korganizer/incidencechanger.cpp
@@ -23,6 +23,7 @@
*/
#include "incidencechanger.h"
+#include "koglobals.h"
#include "koprefs.h"
#include "kogroupware.h"
#include "mailscheduler.h"
@@ -33,24 +34,36 @@
#include <kmessagebox.h>
#include <klocale.h>
+bool IncidenceChanger::beginChange( Incidence *incidence,
+ ResourceCalendar *res, const TQString &subRes )
+{
+ if ( !incidence ) {
+ return false;
+ }
+ kdDebug(5850) << "IncidenceChanger::beginChange for incidence \""
+ << incidence->summary() << "\"" << endl;
-bool IncidenceChanger::beginChange( Incidence * incidence )
-{
- if ( !incidence ) return false;
-kdDebug(5850)<<"IncidenceChanger::beginChange for incidence \""<<incidence->summary()<<"\""<<endl;
- return mCalendar->beginChange( incidence );
+ CalendarResources *calRes = dynamic_cast<CalendarResources*>( mCalendar );
+ if ( !calRes ) {
+ return false;
+ }
+
+ return calRes->beginChange( incidence, res, subRes );
}
-bool IncidenceChanger::sendGroupwareMessage( Incidence *incidence, KCal::Scheduler::Method method, bool deleting )
+bool IncidenceChanger::sendGroupwareMessage( Incidence *incidence,
+ KCal::Scheduler::Method method,
+ KOGlobals::HowChanged action,
+ TQWidget *parent )
{
if ( KOPrefs::instance()->thatIsMe( incidence->organizer().email() ) && incidence->attendeeCount()>0
&& !KOPrefs::instance()->mUseGroupwareCommunication ) {
emit schedule( method, incidence );
return true;
} else if( KOPrefs::instance()->mUseGroupwareCommunication ) {
- // FIXME: Find a widget to use as parent, instead of 0
- return KOGroupware::instance()->sendICalMessage( 0, method, incidence, deleting );
+ return
+ KOGroupware::instance()->sendICalMessage( parent, method, incidence, action, false );
}
return true;
}
@@ -66,7 +79,7 @@ void IncidenceChanger::cancelAttendees( Incidence *incidence )
// them?", which isn't helpful at all in this situation. Afterwards, it
// would only call the MailScheduler::performTransaction, so do this
// manually.
- // FIXME: Groupware schedulling should be factored out to it's own class
+ // FIXME: Groupware scheduling should be factored out to it's own class
// anyway
KCal::MailScheduler scheduler( mCalendar );
scheduler.performTransaction( incidence, Scheduler::Cancel );
@@ -74,23 +87,36 @@ void IncidenceChanger::cancelAttendees( Incidence *incidence )
}
}
-bool IncidenceChanger::endChange( Incidence *incidence )
+bool IncidenceChanger::endChange( Incidence *incidence,
+ ResourceCalendar *res, const TQString &subRes )
{
// FIXME: if that's a groupware incidence, and I'm not the organizer,
// send out a mail to the organizer with a counterproposal instead
// of actually changing the incidence. Then no locking is needed.
// FIXME: if that's a groupware incidence, and the incidence was
// never locked, we can't unlock it with endChange().
- if ( !incidence ) return false;
- // kdDebug(5850)<<"IncidenceChanger::endChange for incidence \""<<incidence->summary()<<"\""<<endl;
- return mCalendar->endChange( incidence );
+
+ if ( !incidence ) {
+ return false;
+ }
+
+ kdDebug(5850) << "IncidenceChanger::endChange for incidence \""
+ << incidence->summary() << "\"" << endl;
+
+ CalendarResources *calRes = dynamic_cast<CalendarResources*>( mCalendar );
+ if ( !calRes ) {
+ return false;
+ }
+
+ return calRes->endChange( incidence, res, subRes );
}
-bool IncidenceChanger::deleteIncidence( Incidence *incidence )
+bool IncidenceChanger::deleteIncidence( Incidence *incidence, TQWidget *parent )
{
if ( !incidence ) return true;
kdDebug(5850)<<"IncidenceChanger::deleteIncidence for incidence \""<<incidence->summary()<<"\""<<endl;
- bool doDelete = sendGroupwareMessage( incidence, KCal::Scheduler::Cancel );
+ bool doDelete = sendGroupwareMessage( incidence, KCal::Scheduler::Cancel,
+ KOGlobals::INCIDENCEDELETED, parent );
if( doDelete ) {
// @TODO: let Calendar::deleteIncidence do the locking...
Incidence* tmp = incidence->clone();
@@ -113,29 +139,52 @@ kdDebug(5850)<<"IncidenceChanger::deleteIncidence for incidence \""<<incidence->
}
}
- if ( notifyOrganizer ) {
+ if ( !KOGroupware::instance()->doNotNotify() && notifyOrganizer ) {
KCal::MailScheduler scheduler( mCalendar );
scheduler.performTransaction( tmp, Scheduler::Reply );
}
+ //reset the doNotNotify flag
+ KOGroupware::instance()->setDoNotNotify( false );
}
+ emit incidenceDeleted( incidence );
}
- emit incidenceDeleted( incidence );
return doDelete;
}
-bool IncidenceChanger::cutIncidence( Incidence *incidence )
+bool IncidenceChanger::cutIncidences( const Incidence::List &incidences,
+ TQWidget *parent )
{
- if ( !incidence ) return true;
-kdDebug(5850)<<"IncidenceChanger::deleteIncidence for incidence \""<<incidence->summary()<<"\""<<endl;
- bool doDelete = sendGroupwareMessage( incidence, KCal::Scheduler::Cancel );
- if( doDelete ) {
- // @TODO: the factory needs to do the locking!
- DndFactory factory( mCalendar );
- emit incidenceToBeDeleted( incidence );
- factory.cutIncidence( incidence );
- emit incidenceDeleted( incidence );
+ Incidence::List::ConstIterator it;
+ bool doDelete = true;
+ Incidence::List incsToCut;
+ for ( it = incidences.constBegin(); it != incidences.constEnd(); ++it ) {
+ if ( *it ) {
+ doDelete = sendGroupwareMessage( *it, KCal::Scheduler::Cancel,
+ KOGlobals::INCIDENCEDELETED, parent );
+ if ( doDelete ) {
+ emit incidenceToBeDeleted( *it );
+ incsToCut.append( *it );
+ }
+ }
+ }
+
+ DndFactory factory( mCalendar );
+
+ if ( factory.cutIncidences( incsToCut ) ) {
+ for ( it = incsToCut.constBegin(); it != incsToCut.constEnd(); ++it ) {
+ emit incidenceDeleted( *it );
+ }
+ return !incsToCut.isEmpty();
+ } else {
+ return false;
}
- return doDelete;
+}
+
+bool IncidenceChanger::cutIncidence( Incidence *incidence, TQWidget *parent )
+{
+ Incidence::List incidences;
+ incidences.append( incidence );
+ return cutIncidences( incidences, parent );
}
class IncidenceChanger::ComparisonVisitor : public IncidenceBase::Visitor
@@ -277,37 +326,35 @@ bool IncidenceChanger::myAttendeeStatusChanged( Incidence *oldInc, Incidence *ne
}
bool IncidenceChanger::changeIncidence( Incidence *oldinc, Incidence *newinc,
- int action )
+ KOGlobals::WhatChanged action,
+ TQWidget *parent )
{
kdDebug(5850)<<"IncidenceChanger::changeIncidence for incidence \""<<newinc->summary()<<"\" ( old one was \""<<oldinc->summary()<<"\")"<<endl;
- if( incidencesEqual( newinc, oldinc ) ) {
+ if ( incidencesEqual( newinc, oldinc ) ) {
// Don't do anything
kdDebug(5850) << "Incidence not changed\n";
} else {
kdDebug(5850) << "Incidence changed\n";
- bool statusChanged = myAttendeeStatusChanged( oldinc, newinc );
+ bool attendeeStatusChanged = myAttendeeStatusChanged( oldinc, newinc );
int revision = newinc->revision();
newinc->setRevision( revision + 1 );
// FIXME: Use a generic method for this! Ideally, have an interface class
// for group scheduling. Each implementation could then just do what
// it wants with the event. If no groupware is used,use the null
// pattern...
- bool revert = KOPrefs::instance()->mUseGroupwareCommunication;
- if ( revert &&
- KOGroupware::instance()->sendICalMessage( 0,
- KCal::Scheduler::Request,
- newinc, false, statusChanged ) ) {
- // Accept the event changes
- revert = false;
+ bool success = true;
+ if ( KOPrefs::instance()->mUseGroupwareCommunication ) {
+ success = KOGroupware::instance()->sendICalMessage(
+ parent,
+ KCal::Scheduler::Request,
+ newinc, KOGlobals::INCIDENCEEDITED, attendeeStatusChanged );
}
- if ( action<0 ) {
- emit incidenceChanged( oldinc, newinc );
- } else {
+ if ( success ) {
+ // Accept the event changes
emit incidenceChanged( oldinc, newinc, action );
- }
-
- if ( revert ) {
+ } else {
+ // revert changes
assignIncidence( newinc, oldinc );
return false;
}
@@ -315,41 +362,97 @@ kdDebug(5850)<<"IncidenceChanger::changeIncidence for incidence \""<<newinc->sum
return true;
}
-bool IncidenceChanger::addIncidence( Incidence *incidence, TQWidget *parent )
+bool IncidenceChanger::addIncidence( Incidence *incidence,
+ ResourceCalendar *res, const TQString &subRes,
+ TQWidget *parent )
{
-kdDebug(5850)<<"IncidenceChanger::addIncidence for incidence \""<<incidence->summary()<<"\""<<endl;
- if ( KOPrefs::instance()->mUseGroupwareCommunication ) {
- if ( !KOGroupware::instance()->sendICalMessage( parent,
- KCal::Scheduler::Request,
- incidence ) ) {
- kdError() << "sendIcalMessage failed." << endl;
- }
+ CalendarResources *stdcal = dynamic_cast<CalendarResources *>( mCalendar );
+ if( stdcal && !stdcal->hasCalendarResources() ) {
+ KMessageBox::sorry(
+ parent,
+ i18n( "No calendars found, unable to save %1 \"%2\"." ).
+ arg( i18n( incidence->type() ) ).
+ arg( incidence->summary() ) );
+ kdDebug(5850) << "IncidenceChanger: No calendars found" << endl;
+ return false;
}
+
// FIXME: This is a nasty hack, since we need to set a parent for the
// resource selection dialog. However, we don't have any UI methods
// in the calendar, only in the CalendarResources::DestinationPolicy
// So we need to type-cast it and extract it from the CalendarResources
- CalendarResources *stdcal = dynamic_cast<CalendarResources*>(mCalendar);
TQWidget *tmpparent = 0;
if ( stdcal ) {
tmpparent = stdcal->dialogParentWidget();
stdcal->setDialogParentWidget( parent );
}
- bool success = mCalendar->addIncidence( incidence );
- if ( stdcal ) {
- // Reset the parent widget, otherwise we'll end up with pointers to deleted
- // widgets sooner or later
- stdcal->setDialogParentWidget( tmpparent );
+
+ // If a ResourceCalendar isn't provided, then try to compute one
+ // along with any subResource from the incidence.
+ ResourceCalendar *pRes = res;
+ TQString pSubRes = subRes;
+ TQString pResName;
+ if ( !pRes ) {
+ if ( stdcal ) {
+ pRes = stdcal->resource( incidence );
+ if ( pRes ) {
+ pResName = pRes->resourceName();
+ if ( pRes->canHaveSubresources() ) {
+ pSubRes = pRes->subresourceIdentifier( incidence );
+ pResName = pRes->labelForSubresource( pSubRes );
+ }
+ }
+ }
+ }
+
+ bool success = false;
+ if ( stdcal && pRes && !pRes->readOnly() && pRes->subresourceWritable( pSubRes ) ) {
+ success = stdcal->addIncidence( incidence, pRes, pSubRes );
+ } else {
+ success = mCalendar->addIncidence( incidence );
}
+
if ( !success ) {
- KMessageBox::sorry( parent, i18n("Unable to save %1 \"%2\".")
- .arg( i18n( incidence->type() ) )
- .arg( incidence->summary() ) );
+ // We can have a failure if the user pressed [cancel] in the resource
+ // selectdialog, so check the exception.
+ ErrorFormat *e = stdcal ? stdcal->exception() : 0;
+ if ( !e ||
+ ( e && ( e->errorCode() != KCal::ErrorFormat::UserCancel &&
+ e->errorCode() != KCal::ErrorFormat::NoWritableFound ) ) ) {
+ TQString errMessage;
+ if ( pResName.isEmpty() ) {
+ errMessage = i18n( "Unable to save %1 \"%2\"." ).
+ arg( i18n( incidence->type() ) ).
+ arg( incidence->summary() );
+ } else {
+ errMessage = i18n( "Unable to save %1 \"%2\" to calendar %3." ).
+ arg( i18n( incidence->type() ) ).
+ arg( incidence->summary() ).
+ arg( pResName );
+ }
+ KMessageBox::sorry( parent, errMessage );
+ }
+ kdDebug(5850) << "IncidenceChanger: Can't add incidence" << endl;
return false;
}
+
+ if ( KOPrefs::instance()->mUseGroupwareCommunication ) {
+ if ( !KOGroupware::instance()->sendICalMessage(
+ parent,
+ KCal::Scheduler::Request,
+ incidence, KOGlobals::INCIDENCEADDED, false ) ) {
+ KMessageBox::sorry(
+ parent,
+ i18n( "Attempt to send the scheduling message failed. "
+ "Please check your Group Scheduling settings. "
+ "Contact your system administrator for more help.") );
+ }
+ }
+
emit incidenceAdded( incidence );
return true;
}
+
#include "incidencechanger.moc"
#include "incidencechangerbase.moc"
diff --git a/korganizer/incidencechanger.h b/korganizer/incidencechanger.h
index 1423b488..afa55064 100644
--- a/korganizer/incidencechanger.h
+++ b/korganizer/incidencechanger.h
@@ -26,33 +26,53 @@
#include "korganizer/incidencechangerbase.h"
+namespace KCal {
+ class ResourceCalendar;
+}
+
class IncidenceChanger : public KOrg::IncidenceChangerBase
{
-Q_OBJECT
-public:
- IncidenceChanger( Calendar*cal, TQObject *parent ) : IncidenceChangerBase( cal, parent ) {}
- ~IncidenceChanger() {}
-
- bool beginChange( Incidence * incidence );
- bool sendGroupwareMessage( Incidence *incidence, KCal::Scheduler::Method method, bool deleting = false );
- bool endChange( Incidence *incidence );
-
- bool addIncidence( Incidence *incidence, TQWidget *parent = 0 );
- bool changeIncidence( Incidence *oldinc, Incidence *newinc, int action = -1 );
- bool deleteIncidence( Incidence *incidence );
-
- bool cutIncidence( Incidence *incidence );
- static bool incidencesEqual( Incidence *inc1, Incidence *inc2 );
- static bool assignIncidence( Incidence *inc1, Incidence *inc2 );
-public slots:
- void cancelAttendees( Incidence *incidence );
-
-protected:
- bool myAttendeeStatusChanged( Incidence *oldInc, Incidence *newInc );
-
-private:
- class ComparisonVisitor;
- class AssignmentVisitor;
+ Q_OBJECT
+ public:
+ IncidenceChanger( Calendar *cal, TQObject *parent )
+ : IncidenceChangerBase( cal, parent ) {}
+ ~IncidenceChanger() {}
+
+ bool beginChange( Incidence *incidence,
+ ResourceCalendar *res, const TQString &subRes );
+
+ bool sendGroupwareMessage( Incidence *incidence,
+ KCal::Scheduler::Method method,
+ KOGlobals::HowChanged action,
+ TQWidget *parent );
+
+ bool endChange( Incidence *incidence,
+ ResourceCalendar *res, const TQString &subRes );
+
+ bool addIncidence( Incidence *incidence,
+ ResourceCalendar *res, const TQString &subRes,
+ TQWidget *parent );
+
+ bool changeIncidence( Incidence *oldinc, Incidence *newinc,
+ KOGlobals::WhatChanged, TQWidget *parent );
+
+ bool deleteIncidence( Incidence *incidence, TQWidget *parent );
+
+ bool cutIncidences( const Incidence::List &incidences, TQWidget *parent );
+ bool cutIncidence( Incidence *incidence, TQWidget *parent );
+
+ static bool incidencesEqual( Incidence *inc1, Incidence *inc2 );
+ static bool assignIncidence( Incidence *inc1, Incidence *inc2 );
+
+ public slots:
+ void cancelAttendees( Incidence *incidence );
+
+ protected:
+ bool myAttendeeStatusChanged( Incidence *oldInc, Incidence *newInc );
+
+ private:
+ class ComparisonVisitor;
+ class AssignmentVisitor;
};
#endif
diff --git a/korganizer/interfaces/calendar/calendardecoration.desktop b/korganizer/interfaces/calendar/calendardecoration.desktop
index e9763878..b44db80a 100644
--- a/korganizer/interfaces/calendar/calendardecoration.desktop
+++ b/korganizer/interfaces/calendar/calendardecoration.desktop
@@ -28,7 +28,6 @@ Comment[hu]=Naptármegjelenési bővítőmodul
Comment[is]=Íforrit til að skreyta texta dagatals
Comment[it]=Plugin di decorazione del calendario
Comment[ja]=カレンダー装飾プラグイン
-Comment[ka]=კალენდრის გაფორმების მოდული
Comment[kk]=Күнтізбені безендіру модулі
Comment[km]=កម្មវិធី​ជំនួយ​សម្រាប់​តុបតែង​ប្រតិទិន
Comment[lt]=vCalendar dekoracijų priedas
diff --git a/korganizer/interfaces/calendar/calendarplugin.desktop b/korganizer/interfaces/calendar/calendarplugin.desktop
index 765fced7..d5c0ab56 100644
--- a/korganizer/interfaces/calendar/calendarplugin.desktop
+++ b/korganizer/interfaces/calendar/calendarplugin.desktop
@@ -30,7 +30,6 @@ Comment[hu]=Naptárkezelő bővítőmodul
Comment[is]=Dagatals íforrit
Comment[it]=Plugin calendario
Comment[ja]=カレンダープラグイン
-Comment[ka]=კალენდრის მოდული
Comment[kk]=Күнтізбе модулі
Comment[km]=កម្មវិធី​ជំនួយ​ប្រតិទិន
Comment[ko]=달력 플러그인
@@ -61,8 +60,7 @@ Comment[tg]=Модул барои тақвимот
Comment[th]=โปรแกรมเสริมบันทึกประจำวัน
Comment[tr]=Takvim Eklentisi
Comment[uk]=Втулок календаря
-Comment[uz]=Kalendar plagini
-Comment[uz@cyrillic]=Календар плагини
+Comment[uz]=Календар плагини
Comment[ven]=U pulaga ha khalenda
Comment[vi]=Plugin lịch
Comment[xh]=Ikhalenda ye Plugin
diff --git a/korganizer/interfaces/korganizer/baseview.h b/korganizer/interfaces/korganizer/baseview.h
index 64fbd72b..6d60a0a5 100644
--- a/korganizer/interfaces/korganizer/baseview.h
+++ b/korganizer/interfaces/korganizer/baseview.h
@@ -2,7 +2,7 @@
This file is part of the KOrganizer interfaces.
Copyright (c) 1999,2001,2003 Cornelius Schumacher <schumacher@kde.org>
- Copyright (C) 2004 Reinhold Kainhofer <reinhold@kainhofer.com>
+ Copyright (C) 2004 Reinhold Kainhofer <reinhold@kainhofer.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
@@ -38,17 +38,19 @@
using namespace KCal;
-namespace KCal { class Calendar; }
+namespace KCal {
+ class Calendar;
+ class ResourceCalendar;
+}
namespace KOrg {
-
/**
- 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.
+ 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
@@ -56,7 +58,7 @@ namespace KOrg {
*/
class KDE_EXPORT BaseView : public QWidget
{
- Q_OBJECT
+ Q_OBJECT
public:
/**
Constructs a view.
@@ -66,21 +68,41 @@ class KDE_EXPORT BaseView : public QWidget
@param parent parent widget.
@param name name of this widget.
*/
- BaseView( Calendar *cal, TQWidget *parent = 0,
- const char *name = 0 )
- : TQWidget( parent, name ), mCalendar( cal ), mChanger( 0 ) {}
+ BaseView( Calendar *cal, TQWidget *parent = 0, const char *name = 0 )
+ : TQWidget( parent, name ),
+ mReadOnly( false ), mCalendar( cal ), mResource( 0 ), mChanger( 0 ) {}
/**
Destructor. Views will do view-specific cleanups here.
*/
virtual ~BaseView() {}
+ /** Flag indicating if the view is read-only */
+ void setReadOnly( bool readonly ) { mReadOnly = readonly; }
+ bool readOnly() { return mReadOnly; }
+
virtual void setCalendar( Calendar *cal ) { mCalendar = cal; }
/**
Return calendar object of this view.
*/
virtual Calendar *calendar() { return mCalendar; }
+ virtual void setResource( ResourceCalendar *res, const TQString &subResource )
+ {
+ mResource = res;
+ mSubResource = subResource;
+ }
+
+ /**
+ Return resourceCalendar of this view.
+ */
+ ResourceCalendar *resourceCalendar() { return mResource; }
+
+ /**
+ Return subResourceCalendar of this view.
+ */
+ TQString subResourceCalendar() const { return mSubResource; }
+
/**
@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
@@ -93,7 +115,19 @@ class KDE_EXPORT BaseView : public QWidget
select a single event at a time, but some may be able to select
more than one.
*/
- virtual DateList selectedDates() = 0;
+ virtual DateList selectedIncidenceDates() = 0;
+
+ /**
+ Returns the start of the selection, or an invalid TQDateTime if there is no selection
+ or the view doesn't support selecting cells.
+ */
+ virtual TQDateTime selectionStart() { return TQDateTime(); }
+
+ /**
+ Returns the end of the selection, or an invalid TQDateTime if there is no selection
+ or the view doesn't support selecting cells.
+ */
+ virtual TQDateTime selectionEnd() { return TQDateTime(); }
virtual CalPrinterBase::PrintType printType()
{
@@ -108,6 +142,11 @@ class KDE_EXPORT BaseView : public QWidget
/** Return if this view is a view for displaying events. */
virtual bool isEventView() { return false; }
+ /** Returns true if the view supports navigation through the date navigator
+ ( selecting a date range, changing month, changing year, etc. )
+ */
+ virtual bool supportsDateNavigation() const { return false; }
+
public slots:
/**
Show incidences for the given date range. The date range actually shown may be
@@ -124,8 +163,9 @@ class KDE_EXPORT BaseView : public QWidget
show all given events.
@param incidenceList a list of incidences to show.
+ @param date is the TQDate on which the incidences are being shown.
*/
- virtual void showIncidences( const Incidence::List &incidenceList ) = 0;
+ virtual void showIncidences( const Incidence::List &incidenceList, const TQDate &date ) = 0;
/**
Updates the current display to reflect changes that may have happened
@@ -166,19 +206,19 @@ class KDE_EXPORT BaseView : public QWidget
virtual bool eventDurationHint(TQDateTime &/*startDt*/, TQDateTime &/*endDt*/, bool &/*allDay*/) { return false; }
signals:
- void incidenceSelected( Incidence * );
+ void incidenceSelected( Incidence *, const TQDate & );
/**
* instructs the receiver to show the incidence in read-only mode.
*/
- void showIncidenceSignal(Incidence *);
+ void showIncidenceSignal( Incidence *, const TQDate & );
/**
* 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 editIncidenceSignal( Incidence *, const TQDate & );
/**
* instructs the receiver to delete the Incidence in some manner; some
@@ -220,31 +260,40 @@ class KDE_EXPORT BaseView : public QWidget
* instructs the receiver to create a new event. Doesn't make
* sense to connect to more than one receiver.
*/
- void newEventSignal();
+ void newEventSignal( ResourceCalendar *res, const TQString &subResource );
/**
* 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( const TQDate & );
+ void newEventSignal( ResourceCalendar *res, const TQString &subResource,
+ const TQDate & );
/**
* 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( const TQDateTime & );
+ void newEventSignal( ResourceCalendar *res, const TQString &subResource,
+ const TQDateTime & );
/**
* 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( const TQDateTime &, const TQDateTime & );
+ void newEventSignal( ResourceCalendar *res, const TQString &subResource,
+ const TQDateTime &, const TQDateTime & );
- void newTodoSignal( const TQDate & );
+ void newTodoSignal( ResourceCalendar *res,const TQString &subResource,
+ const TQDate & );
void newSubTodoSignal( Todo * );
- void newJournalSignal( const TQDate & );
+ void newJournalSignal( ResourceCalendar *res,const TQString &subResource,
+ const TQDate & );
private:
+ bool mReadOnly;
Calendar *mCalendar;
+ ResourceCalendar *mResource;
+ TQString mSubResource;
+
protected:
IncidenceChangerBase *mChanger;
};
diff --git a/korganizer/interfaces/korganizer/corehelper.h b/korganizer/interfaces/korganizer/corehelper.h
index 53b5d9fb..8c69a1ad 100644
--- a/korganizer/interfaces/korganizer/corehelper.h
+++ b/korganizer/interfaces/korganizer/corehelper.h
@@ -37,8 +37,7 @@ class CoreHelper
public:
CoreHelper() {}
virtual ~CoreHelper() {}
-
- virtual TQColor defaultEventColor() = 0;
+
virtual TQColor textColor( const TQColor &bgColor ) = 0;
virtual TQColor categoryColor( const TQStringList &cats ) = 0;
virtual TQString holidayString( const TQDate &dt ) = 0;
diff --git a/korganizer/interfaces/korganizer/incidencechangerbase.h b/korganizer/interfaces/korganizer/incidencechangerbase.h
index f482388c..e7c13305 100644
--- a/korganizer/interfaces/korganizer/incidencechangerbase.h
+++ b/korganizer/interfaces/korganizer/incidencechangerbase.h
@@ -21,13 +21,16 @@
#ifndef KORG_INCIDENCECHANGERBASE_H
#define KORG_INCIDENCECHANGERBASE_H
+#include "korganizer/koglobals.h"
#include <libkcal/scheduler.h>
+#include <libkcal/incidence.h>
#include <tqobject.h>
class TQWidget;
namespace KCal {
-class Calendar;
-class Incidence;
+ class Calendar;
+ class Incidence;
+ class ResourceCalendar;
}
using namespace KCal;
@@ -42,25 +45,29 @@ public:
virtual ~IncidenceChangerBase() {}
virtual bool sendGroupwareMessage( Incidence *incidence,
- KCal::Scheduler::Method method, bool deleting = false ) = 0;
+ KCal::Scheduler::Method method,
+ KOGlobals::HowChanged action,
+ TQWidget *parent ) = 0;
- virtual bool beginChange( Incidence * incidence ) = 0;
- virtual bool endChange( Incidence *incidence ) = 0;
+ virtual bool beginChange( Incidence *incidence,
+ ResourceCalendar *res, const TQString &subRes ) = 0;
+ virtual bool endChange( Incidence *incidence,
+ ResourceCalendar *res, const TQString &subRes ) = 0;
- virtual bool addIncidence( Incidence *incidence, TQWidget *parent = 0 ) = 0;
- virtual bool changeIncidence( Incidence *newinc, Incidence *oldinc,
- int action = -1 ) = 0;
- virtual bool deleteIncidence( Incidence *incidence ) = 0;
- virtual bool cutIncidence( Incidence *incidence ) = 0;
+ virtual bool addIncidence( Incidence *incidence,
+ ResourceCalendar *res, const TQString &subRes,
+ TQWidget *parent ) = 0;
+
+ virtual bool changeIncidence( Incidence *oldinc, Incidence *newinc,
+ KOGlobals::WhatChanged, TQWidget *parent ) = 0;
+ virtual bool deleteIncidence( Incidence *incidence, TQWidget *parent ) = 0;
+
+ virtual bool cutIncidences( const Incidence::List &incidences, TQWidget *parent ) = 0;
+ virtual bool cutIncidence( Incidence *incidence, TQWidget *parent ) = 0;
-/*
- static bool incidencesEqual( Incidence *inc1, Incidence *inc2 );
- static bool assignIncidence( Incidence *inc1, Incidence *inc2 );
-*/
signals:
void incidenceAdded( Incidence * );
- void incidenceChanged( Incidence *oldInc, Incidence *newInc, int );
- void incidenceChanged( Incidence *oldInc, Incidence *newInc );
+ void incidenceChanged( Incidence *oldInc, Incidence *newInc, KOGlobals::WhatChanged );
void incidenceToBeDeleted( Incidence * );
void incidenceDeleted( Incidence * );
diff --git a/korganizer/interfaces/korganizer/korganizerpart.desktop b/korganizer/interfaces/korganizer/korganizerpart.desktop
index 7cb419de..c1b84659 100644
--- a/korganizer/interfaces/korganizer/korganizerpart.desktop
+++ b/korganizer/interfaces/korganizer/korganizerpart.desktop
@@ -25,7 +25,6 @@ Comment[hu]=KOrganizer objektum
Comment[is]=KOrganizer hluti
Comment[it]=Parte di KOrganizer
Comment[ja]=KOrganizer パート
-Comment[ka]=KOrganizer კომპონენტი
Comment[kk]=KOrganizer бөлшегі
Comment[km]=ផ្នែក​របស់ KOrganizer
Comment[lt]=KOrganizer dalis
diff --git a/korganizer/interfaces/korganizer/korgprintplugin.desktop b/korganizer/interfaces/korganizer/korgprintplugin.desktop
index ffa520d3..05cbd1b9 100644
--- a/korganizer/interfaces/korganizer/korgprintplugin.desktop
+++ b/korganizer/interfaces/korganizer/korgprintplugin.desktop
@@ -25,7 +25,6 @@ Comment[hu]=KOrganizer objektum
Comment[is]=KOrganizer hluti
Comment[it]=Parte di KOrganizer
Comment[ja]=KOrganizer パート
-Comment[ka]=KOrganizer კომპონენტი
Comment[kk]=KOrganizer бөлшегі
Comment[km]=ផ្នែក​របស់ KOrganizer
Comment[lt]=KOrganizer dalis
diff --git a/korganizer/interfaces/korganizer/mainwindow.h b/korganizer/interfaces/korganizer/mainwindow.h
index 3343470a..dcda1bee 100644
--- a/korganizer/interfaces/korganizer/mainwindow.h
+++ b/korganizer/interfaces/korganizer/mainwindow.h
@@ -87,9 +87,11 @@ class MainWindow
*/
virtual void setTitle() = 0;
- void setHasDocument( bool d ) { mDocument = d; }
+ void setHasDocument( bool d ) { mDocument = d; }
bool hasDocument() const { return mDocument; }
+ virtual bool isCurrentlyActivePart() = 0;
+
private:
bool mDocument;
};
diff --git a/korganizer/journalentry.cpp b/korganizer/journalentry.cpp
index ae80a8d6..c107d618 100644
--- a/korganizer/journalentry.cpp
+++ b/korganizer/journalentry.cpp
@@ -128,8 +128,8 @@ void JournalDateEntry::addJournal( Journal *j )
entry, TQT_SLOT( flushEntry() ) );
connect( entry, TQT_SIGNAL( deleteIncidence( Incidence* ) ),
this, TQT_SIGNAL( deleteIncidence( Incidence* ) ) );
- connect( entry, TQT_SIGNAL( editIncidence( Incidence* ) ),
- this, TQT_SIGNAL( editIncidence( Incidence* ) ) );
+ connect( entry, TQT_SIGNAL( editIncidence( Incidence*, const TQDate& ) ),
+ this, TQT_SIGNAL( editIncidence( Incidence*, const TQDate& ) ) );
}
Journal::List JournalDateEntry::journals() const
@@ -151,7 +151,7 @@ void JournalDateEntry::setIncidenceChanger( IncidenceChangerBase *changer )
void JournalDateEntry::emitNewJournal()
{
- emit newJournal( mDate );
+ emit newJournal( 0/*ResourceCalendar*/, TQString()/*subResource*/, mDate );
}
void JournalDateEntry::journalEdited( Journal *journal )
@@ -271,8 +271,9 @@ void JournalEntry::deleteItem()
void JournalEntry::editItem()
{
writeJournal();
- if ( mJournal )
- emit editIncidence( mJournal );
+ if ( mJournal ) {
+ emit editIncidence( mJournal, mJournal->dtStart().date() );
+ }
}
void JournalEntry::printItem()
@@ -381,17 +382,17 @@ void JournalEntry::writeJournal()
newJournal = true;
mJournal = new Journal;
writeJournalPrivate( mJournal );
- if ( !mChanger->addIncidence( mJournal, this ) ) {
+ if ( !mChanger->addIncidence( mJournal, 0, TQString(), this ) ) {
KODialogManager::errorSaveIncidence( this, mJournal );
delete mJournal;
mJournal = 0;
}
} else {
oldJournal = mJournal->clone();
- if ( mChanger->beginChange( mJournal ) ) {
+ if ( mChanger->beginChange( mJournal, 0, TQString() ) ) {
writeJournalPrivate( mJournal );
- mChanger->changeIncidence( oldJournal, mJournal, KOGlobals::DESCRIPTION_MODIFIED );
- mChanger->endChange( mJournal );
+ mChanger->changeIncidence( oldJournal, mJournal, KOGlobals::DESCRIPTION_MODIFIED, this );
+ mChanger->endChange( mJournal, 0, TQString() );
}
delete oldJournal;
}
diff --git a/korganizer/journalentry.h b/korganizer/journalentry.h
index 090909f3..9350d5ea 100644
--- a/korganizer/journalentry.h
+++ b/korganizer/journalentry.h
@@ -26,6 +26,7 @@
//
// Widget showing one Journal entry
+#include <libkcal/resourcecalendar.h>
#include <tqvbox.h>
class TQLabel;
@@ -78,7 +79,7 @@ class JournalEntry : public TQWidget {
signals:
void deleteIncidence( Incidence * );
- void editIncidence( Incidence * );
+ void editIncidence( Incidence *, const TQDate& );
protected:
void clearFields();
@@ -131,9 +132,9 @@ class JournalDateEntry : public TQVBox {
void setIncidenceChangerSignal( IncidenceChangerBase *changer );
void setDateSignal( const TQDate & );
void flushEntries();
- void editIncidence( Incidence * );
+ void editIncidence( Incidence *, const TQDate& );
void deleteIncidence( Incidence * );
- void newJournal( const TQDate & );
+ void newJournal( ResourceCalendar *, const TQString &, const TQDate & );
public slots:
void emitNewJournal();
diff --git a/korganizer/kcalendariface.h b/korganizer/kcalendariface.h
index a63f3f1c..f4a20d7a 100644
--- a/korganizer/kcalendariface.h
+++ b/korganizer/kcalendariface.h
@@ -86,7 +86,8 @@ class KCalendarIface : public DCOPObject
const TQString& uri,
const TQString& file,
const TQStringList& attendees,
- const TQString& attachmentMimetype ) = 0;
+ const TQString& attachmentMimetype,
+ bool isTask ) = 0;
virtual void openJournalEditor( const TQDate& date ) = 0;
virtual void openJournalEditor( const TQString& text,
diff --git a/korganizer/kdatenavigator.cpp b/korganizer/kdatenavigator.cpp
index 1dea017a..6fe79459 100644
--- a/korganizer/kdatenavigator.cpp
+++ b/korganizer/kdatenavigator.cpp
@@ -53,11 +53,12 @@ KDateNavigator::KDateNavigator( TQWidget *parent, const char *name )
mNavigatorBar = new NavigatorBar( this );
topLayout->addMultiCellWidget( mNavigatorBar, 0, 0, 0, 7 );
- connect( mNavigatorBar, TQT_SIGNAL( goPrevYear() ), TQT_SIGNAL( goPrevYear() ) );
- connect( mNavigatorBar, TQT_SIGNAL( goPrevMonth() ), TQT_SIGNAL( goPrevMonth() ) );
- connect( mNavigatorBar, TQT_SIGNAL( goNextMonth() ), TQT_SIGNAL( goNextMonth() ) );
- connect( mNavigatorBar, TQT_SIGNAL( goNextYear() ), TQT_SIGNAL( goNextYear() ) );
- connect( mNavigatorBar, TQT_SIGNAL( goMonth( int ) ), TQT_SIGNAL( goMonth( int ) ) );
+ connect( mNavigatorBar, TQT_SIGNAL( prevYearClicked() ), TQT_SIGNAL( prevYearClicked() ) );
+ connect( mNavigatorBar, TQT_SIGNAL( prevMonthClicked() ), TQT_SIGNAL( prevMonthClicked() ) );
+ connect( mNavigatorBar, TQT_SIGNAL( nextMonthClicked() ), TQT_SIGNAL( nextMonthClicked() ) );
+ connect( mNavigatorBar, TQT_SIGNAL( nextYearClicked() ), TQT_SIGNAL( nextYearClicked() ) );
+ connect( mNavigatorBar, TQT_SIGNAL( monthSelected( int ) ), TQT_SIGNAL( monthSelected( int ) ) );
+ connect( mNavigatorBar, TQT_SIGNAL( yearSelected( int ) ), TQT_SIGNAL( yearSelected( int ) ) );
int i;
TQString generalFont = KGlobalSettings::generalFont().family();
@@ -136,6 +137,7 @@ void KDateNavigator::updateToday()
mDayMatrix->recalculateToday();
mDayMatrix->repaint();
}
+
TQDate KDateNavigator::startDate() const
{
// Find the first day of the week of the current month.
@@ -160,6 +162,7 @@ TQDate KDateNavigator::startDate() const
return dayone;
}
+
TQDate KDateNavigator::endDate() const
{
return startDate().addDays( 6*7 );
@@ -202,6 +205,23 @@ void KDateNavigator::updateDayMatrix()
mDayMatrix->repaint();
}
+void KDateNavigator::setUpdateNeeded()
+{
+ mDayMatrix->setUpdateNeeded();
+}
+
+TQDate KDateNavigator::month() const
+{
+ TQDate firstCell = startDate();
+ const KCalendarSystem *calSys = KOGlobals::self()->calendarSystem();
+
+ if ( calSys->day( firstCell ) == 1 ) {
+ return firstCell;
+ } else {
+ calSys->setYMD( firstCell, calSys->year( firstCell ), calSys->month( firstCell ), 1 );
+ return calSys->addMonths( firstCell, 1 );
+ }
+}
void KDateNavigator::updateView()
{
@@ -230,10 +250,11 @@ void KDateNavigator::updateConfig()
void KDateNavigator::setShowWeekNums( bool enabled )
{
for( int i = 0; i < 6; i++ ) {
- if( enabled )
+ if ( enabled ) {
mWeeknos[i]->show();
- else
+ } else {
mWeeknos[i]->hide();
+ }
}
}
@@ -251,15 +272,18 @@ void KDateNavigator::selectDates( const DateList &dateList )
}
}
-void KDateNavigator::wheelEvent ( TQWheelEvent *e )
+void KDateNavigator::wheelEvent( TQWheelEvent *e )
{
- if( e->delta() > 0 ) emit goPrevious();
- else emit goNext();
+ if ( e->delta() > 0 ) {
+ emit goPrevious();
+ } else {
+ emit goNext();
+ }
e->accept();
}
-bool KDateNavigator::eventFilter ( TQObject *o, TQEvent *e )
+bool KDateNavigator::eventFilter( TQObject *o, TQEvent *e )
{
if ( e->type() == TQEvent::MouseButtonPress ) {
int i;
diff --git a/korganizer/kdatenavigator.h b/korganizer/kdatenavigator.h
index 04792589..682a9358 100644
--- a/korganizer/kdatenavigator.h
+++ b/korganizer/kdatenavigator.h
@@ -63,6 +63,14 @@ class KDateNavigator: public QFrame
NavigatorBar *navigatorBar() const { return mNavigatorBar; }
TQDate startDate() const;
TQDate endDate() const;
+ void setUpdateNeeded();
+
+ /**
+ Returns the current displayed month.
+ It's a TQDate instead of uint so it can be easily feed to KCalendarSystem's
+ functions.
+ */
+ TQDate month() const;
public slots:
void selectDates( const KCal::DateList & );
@@ -75,24 +83,24 @@ class KDateNavigator: public QFrame
void datesSelected( const KCal::DateList & );
void incidenceDropped( Incidence *, const TQDate & );
void incidenceDroppedMove( Incidence *, const TQDate & );
- void weekClicked( const TQDate &);
+ void weekClicked( const TQDate & );
void goPrevious();
void goNext();
+ void nextMonthClicked();
+ void prevMonthClicked();
+ void nextYearClicked();
+ void prevYearClicked();
- void goNextMonth();
- void goPrevMonth();
- void goNextYear();
- void goPrevYear();
-
- void goMonth( int month );
+ void monthSelected( int month );
+ void yearSelected( int year );
protected:
void updateDates();
void wheelEvent( TQWheelEvent * );
- bool eventFilter( TQObject *,TQEvent * );
+ bool eventFilter( TQObject *, TQEvent * );
void setShowWeekNums( bool enabled );
diff --git a/korganizer/koagenda.cpp b/korganizer/koagenda.cpp
index 589c1328..8329d161 100644
--- a/korganizer/koagenda.cpp
+++ b/korganizer/koagenda.cpp
@@ -58,11 +58,12 @@
#include <libkcal/vcaldrag.h>
#include <libkcal/calendar.h>
#include <libkcal/calendarresources.h>
+#include <libkcal/calhelper.h>
#include <math.h>
////////////////////////////////////////////////////////////////////////////
-MarcusBains::MarcusBains(KOAgenda *_agenda,const char *name)
- : TQFrame(_agenda->viewport(),name), agenda(_agenda)
+MarcusBains::MarcusBains(KOAgenda *_agenda,const char *name )
+ : TQFrame(_agenda->viewport(), name), agenda(_agenda)
{
setLineWidth(0);
setMargin(0);
@@ -80,7 +81,8 @@ MarcusBains::MarcusBains(KOAgenda *_agenda,const char *name)
agenda->addChild(mTimeBox);
- oldToday = -1;
+ mOldTime = TQTime( 0, 0 );
+ mOldToday = -1;
}
MarcusBains::~MarcusBains()
@@ -99,33 +101,41 @@ int MarcusBains::todayColumn()
if((*it) == currentDate)
return KOGlobals::self()->reverseLayout() ?
agenda->columns() - 1 - col : col;
- ++col;
+ ++col;
}
return -1;
}
-void MarcusBains::updateLocation(bool recalculate)
+void MarcusBains::updateLocation()
+{
+ updateLocationRecalc();
+}
+
+void MarcusBains::updateLocationRecalc( bool recalculate )
{
TQTime tim = TQTime::currentTime();
- if((tim.hour() == 0) && (oldTime.hour()==23))
+ if((tim.hour() == 0) && (mOldTime.hour()==23))
recalculate = true;
int mins = tim.hour()*60 + tim.minute();
int minutesPerCell = 24 * 60 / agenda->rows();
int y = int( mins * agenda->gridSpacingY() / minutesPerCell );
- int today = recalculate ? todayColumn() : oldToday;
+ int today = recalculate ? todayColumn() : mOldToday;
int x = int( agenda->gridSpacingX() * today );
- bool disabled = !(KOPrefs::instance()->mMarcusBainsEnabled);
- oldTime = tim;
- oldToday = today;
+ mOldTime = tim;
+ mOldToday = today;
- if(disabled || (today<0)) {
+ bool hideIt = !( KOPrefs::instance()->mMarcusBainsEnabled );
+
+ if ( !isHidden() && ( hideIt || ( today < 0 ) ) ) {
hide();
mTimeBox->hide();
return;
- } else {
+ }
+
+ if ( isHidden() && !hideIt ) {
show();
mTimeBox->show();
}
@@ -137,8 +147,12 @@ void MarcusBains::updateLocation(bool recalculate)
if(recalculate)
mTimeBox->setFont(KOPrefs::instance()->mMarcusBainsFont);
- mTimeBox->setText(KGlobal::locale()->formatTime(tim, KOPrefs::instance()->mMarcusBainsShowSeconds));
- mTimeBox->adjustSize();
+ TQString timeStr = KGlobal::locale()->formatTime(tim, KOPrefs::instance()->mMarcusBainsShowSeconds);
+ TQFontMetrics fm = fontMetrics();
+ mTimeBox->setText( timeStr );
+ TQSize sz( fm.width( timeStr + ' ' ), fm.height() );
+ mTimeBox->setFixedSize( sz );
+
if (y-mTimeBox->height()>=0) y-=mTimeBox->height(); else y++;
if (x-mTimeBox->width()+agenda->gridSpacingX() > 0)
x += int( agenda->gridSpacingX() - mTimeBox->width() - 1 );
@@ -157,13 +171,19 @@ void MarcusBains::updateLocation(bool recalculate)
/*
Create an agenda widget with rows rows and columns columns.
*/
-KOAgenda::KOAgenda( int columns, int rows, int rowSize, TQWidget *parent,
- const char *name, WFlags f )
+KOAgenda::KOAgenda( int columns, int rows, int rowSize, CalendarView *calendarView,
+ TQWidget *parent, const char *name, WFlags f )
: TQScrollView( parent, name, f ), mChanger( 0 )
{
mColumns = columns;
mRows = rows;
mGridSpacingY = rowSize;
+ if ( mGridSpacingY < 4 || mGridSpacingY > 30 ) {
+ mGridSpacingY = 10;
+ }
+
+ mCalendarView = calendarView;
+
mAllDayMode = false;
init();
@@ -175,13 +195,14 @@ KOAgenda::KOAgenda( int columns, int rows, int rowSize, TQWidget *parent,
Create an agenda widget with columns columns and one row. This is used for
all-day events.
*/
-KOAgenda::KOAgenda( int columns, TQWidget *parent, const char *name, WFlags f )
- : TQScrollView( parent, name, f )
+KOAgenda::KOAgenda( int columns, CalendarView *calendarView, TQWidget *parent,
+ const char *name, WFlags f ) : TQScrollView( parent, name, f )
{
mColumns = columns;
mRows = 1;
mGridSpacingY = 24;
mAllDayMode = true;
+ mCalendarView = calendarView;
setVScrollBarMode( AlwaysOff );
init();
@@ -214,6 +235,16 @@ const TQString KOAgenda::lastSelectedUid() const
void KOAgenda::init()
{
mGridSpacingX = 100;
+ mDesiredGridSpacingY = KOPrefs::instance()->mHourSize;
+ if ( mDesiredGridSpacingY < 4 || mDesiredGridSpacingY > 30 ) {
+ mDesiredGridSpacingY = 10;
+ }
+
+ // make sure that there are not more than 24 per day
+ mGridSpacingY = (double)height() / (double)mRows;
+ if ( mGridSpacingY < mDesiredGridSpacingY ) {
+ mGridSpacingY = mDesiredGridSpacingY;
+ }
mResizeBorderWidth = 8;
mScrollBorderWidth = 8;
@@ -243,6 +274,7 @@ void KOAgenda::init()
mClickedItem = 0;
mActionItem = 0;
+ mResPair = qMakePair( static_cast<ResourceCalendar *>( 0 ), TQString() );
mActionType = NOP;
mItemMoved = false;
@@ -317,7 +349,7 @@ void KOAgenda::clearSelection()
void KOAgenda::marcus_bains()
{
- if(mMarcusBains) mMarcusBains->updateLocation(true);
+ if(mMarcusBains) mMarcusBains->updateLocationRecalc( true );
}
@@ -510,7 +542,8 @@ bool KOAgenda::eventFilter_key( TQObject *, TQKeyEvent *ke )
void KOAgenda::emitNewEventForSelection()
{
- emit newEventSignal();
+ QPair<ResourceCalendar *, TQString>p = mCalendarView->viewSubResourceCalendar();
+ emit newEventSignal( p.first, p.second );
}
void KOAgenda::finishTypeAhead()
@@ -572,14 +605,17 @@ bool KOAgenda::eventFilter_mouse(TQObject *object, TQMouseEvent *me)
switch (me->type()) {
case TQEvent::MouseButtonPress:
-// kdDebug(5850) << "koagenda: filtered button press" << endl;
+// kdDebug(5850) << "koagenda: filtered button press" << endl;
if (object != viewport()) {
if (me->button() == RightButton) {
mClickedItem = dynamic_cast<KOAgendaItem *>(object);
if (mClickedItem) {
selectItem(mClickedItem);
- emit showIncidencePopupSignal( mClickedItem->incidence(),
+ emit showIncidencePopupSignal( mCalendar,
+ mClickedItem->incidence(),
mClickedItem->itemDate() );
+ } else {
+ return TQScrollView::eventFilter( object, me ); // pass through for use by multiagenda
}
} else {
KOAgendaItem* item = dynamic_cast<KOAgendaItem *>(object);
@@ -587,8 +623,10 @@ bool KOAgenda::eventFilter_mouse(TQObject *object, TQMouseEvent *me)
Incidence *incidence = item->incidence();
if ( incidence->isReadOnly() ) {
mActionItem = 0;
+ mResPair = qMakePair( static_cast<ResourceCalendar *>( 0 ), TQString() );
} else {
mActionItem = item;
+ mResPair = CalHelper::incSubResourceCalendar( mCalendar, incidence );
startItemAction(viewportPos);
}
// Warning: do selectItem() as late as possible, since all
@@ -596,11 +634,12 @@ bool KOAgenda::eventFilter_mouse(TQObject *object, TQMouseEvent *me)
// this filter being run again and mActionItem being set to
// null.
selectItem( item );
+ } else {
+ return TQScrollView::eventFilter( object, me ); // pass through for use by multiagenda
}
}
} else {
- if (me->button() == RightButton)
- {
+ if ( me->button() == RightButton ) {
// if mouse pointer is not in selection, select the cell below the cursor
TQPoint gpos = contentsToGrid( viewportToContents( viewportPos ) );
if ( !ptInSelection( gpos ) ) {
@@ -612,18 +651,18 @@ bool KOAgenda::eventFilter_mouse(TQObject *object, TQMouseEvent *me)
updateContents();
}
showNewEventPopupSignal();
- }
- else
- {
+ } else {
// if mouse pointer is in selection, don't change selection
TQPoint gpos = contentsToGrid( viewportToContents( viewportPos ) );
if ( !ptInSelection( gpos ) ) {
selectItem(0);
mActionItem = 0;
+ mResPair = qMakePair( static_cast<ResourceCalendar *>( 0 ), TQString() );
setCursor(arrowCursor);
startSelectAction(viewportPos);
}
}
+ return TQScrollView::eventFilter( object, me ); // pass through for use by multiagenda
}
break;
@@ -668,29 +707,30 @@ bool KOAgenda::eventFilter_mouse(TQObject *object, TQMouseEvent *me)
} // If we have an action item
} // If move item && !read only
} else {
- if ( mActionType == SELECT ) {
- performSelectAction( viewportPos );
-
- // show cursor at end of timespan
- if ( ((mStartCell.y() < mEndCell.y()) && (mEndCell.x() >= mStartCell.x())) ||
- (mEndCell.x() > mStartCell.x()) )
- indicatorPos = gridToContents( TQPoint(mEndCell.x(), mEndCell.y()+1) );
- else
- indicatorPos = gridToContents( mEndCell );
- }
+ if ( mActionType == SELECT ) {
+ performSelectAction( viewportPos );
+
+ // show cursor at end of timespan
+ if ( ((mStartCell.y() < mEndCell.y()) && (mEndCell.x() >= mStartCell.x())) ||
+ (mEndCell.x() > mStartCell.x()) )
+ indicatorPos = gridToContents( TQPoint(mEndCell.x(), mEndCell.y()+1) );
+ else
+ indicatorPos = gridToContents( mEndCell );
}
+ }
emit mousePosSignal( indicatorPos );
break; }
case TQEvent::MouseButtonDblClick:
if (object == viewport()) {
selectItem(0);
- emit newEventSignal();
+ QPair<ResourceCalendar *, TQString>p = mCalendarView->viewSubResourceCalendar();
+ emit newEventSignal( p.first, p.second );
} else {
- KOAgendaItem *doubleClickedItem = dynamic_cast<KOAgendaItem *>(object);
- if (doubleClickedItem) {
- selectItem(doubleClickedItem);
- emit editIncidenceSignal(doubleClickedItem->incidence());
+ KOAgendaItem *doubleClickedItem = dynamic_cast<KOAgendaItem *>( object );
+ if ( doubleClickedItem ) {
+ selectItem( doubleClickedItem );
+ emit editIncidenceSignal( doubleClickedItem->incidence(), doubleClickedItem->itemDate() );
}
}
break;
@@ -878,10 +918,9 @@ void KOAgenda::performItemAction(const TQPoint& viewportPos)
emit startDragSignal( mActionItem->incidence() );
setCursor( arrowCursor );
mActionItem = 0;
+ mResPair = qMakePair( static_cast<ResourceCalendar *>( 0 ), TQString() );
mActionType = NOP;
mItemMoved = false;
- if ( mItemMoved && mChanger )
- mChanger->endChange( mActionItem->incidence() );
return;
}
} else {
@@ -902,7 +941,8 @@ void KOAgenda::performItemAction(const TQPoint& viewportPos)
// Move or resize item if necessary
if ( mEndCell != gpos ) {
if ( !mItemMoved ) {
- if ( !mChanger || !mChanger->beginChange( mActionItem->incidence() ) ) {
+ if ( !mChanger ||
+ !mChanger->beginChange( mActionItem->incidence(), mResPair.first, mResPair.second ) ) {
KMessageBox::information( this, i18n("Unable to lock item for "
"modification. You cannot make any changes."),
i18n("Locking Failed"), "AgendaLockingFailed" );
@@ -912,6 +952,7 @@ void KOAgenda::performItemAction(const TQPoint& viewportPos)
placeSubCells( mActionItem );
setCursor( arrowCursor );
mActionItem = 0;
+ mResPair = qMakePair( static_cast<ResourceCalendar *>( 0 ), TQString() );
mActionType = NOP;
mItemMoved = false;
return;
@@ -951,7 +992,7 @@ void KOAgenda::performItemAction(const TQPoint& viewportPos)
addChild( newFirst, cpos.x(), cpos.y() );
} else {
newFirst = insertItem( moveItem->incidence(), moveItem->itemDate(),
- moveItem->cellXLeft()-1, rows()+newY, rows()-1 ) ;
+ moveItem->cellXLeft()-1, rows()+newY, rows()-1, moveItem->itemPos(), moveItem->itemCount() ) ;
}
if (newFirst) newFirst->show();
moveItem->prependMoveItem(newFirst);
@@ -996,7 +1037,7 @@ void KOAgenda::performItemAction(const TQPoint& viewportPos)
addChild( newLast, cpos.x(), cpos.y() );
} else {
newLast = insertItem( moveItem->incidence(), moveItem->itemDate(),
- moveItem->cellXLeft()+1, 0, newY-rows()-1 ) ;
+ moveItem->cellXLeft()+1, 0, newY-rows()-1, moveItem->itemPos(), moveItem->itemCount() ) ;
}
moveItem->appendMoveItem( newLast );
newLast->show();
@@ -1046,98 +1087,45 @@ void KOAgenda::endItemAction()
bool multiModify = false;
// FIXME: do the cloning here...
Incidence* inc = mActionItem->incidence();
- // Store modification information in case it is needed to recreate the changes with a new actionitem...
- int mai_xl = mActionItem->cellXLeft();
- int mai_xr = mActionItem->cellXRight();
- int mai_yt = mActionItem->cellYTop();
- int mai_yb = mActionItem->cellYBottom();
- Incidence* newInc;
+
+ if ( mStartCell.x() == mEndCell.x() && mStartCell.y() == mEndCell.y() ) {
+ // not really moved, so stop any change
+ if ( mItemMoved ) {
+ mItemMoved = false;
+ mChanger->endChange( inc, mResPair.first, mResPair.second );
+ }
+ }
if ( mItemMoved ) {
- bool modify = true;
+ Incidence *incToChange = inc;
if ( mActionItem->incidence()->doesRecur() ) {
- int res = KOMessageBox::fourBtnMsgBox( this, TQMessageBox::Question,
- i18n("The item you try to change is a recurring item. Shall the changes "
- "be applied only to this single occurrence, only to the future items, "
- "or to all items in the recurrence?"),
- i18n("Changing Recurring Item"),
- i18n("Only &This Item"), i18n("Only &Future Items"), i18n("&All Occurrences") );
- switch ( res ) {
- case KMessageBox::Ok: // All occurrences
- // Moving the whole sequene of events is handled by the itemModified below.
- modify = true;
- break;
- // FIXME: The following two cases do the following bad things:
- // 1. Pop up a message box asking which resource to save the disassociated event to (!)
- // 2. Crash at mActionItem->endMove(); below.
- case KMessageBox::Yes: { // Just this occurrence
- // Dissociate this occurrence:
- // create clone of event, set relation to old event, set cloned event
- // for mActionItem, add exception date to old event, changeIncidence
- // for the old event, remove the recurrence from the new copy and then just
- // go on with the newly adjusted mActionItem and let the usual code take
- // care of the new time!
- modify = true;
- multiModify = true;
- emit startMultiModify( i18n("Dissociate event from recurrence") );
- Incidence* oldInc = mActionItem->incidence();
- Incidence* oldIncSaved = mActionItem->incidence()->clone();
- newInc = mCalendar->dissociateOccurrence(
- oldInc, mActionItem->itemDate() );
- if ( newInc ) {
- // don't recreate items, they already have the correct position
- emit enableAgendaUpdate( false );
- mActionItem->dissociateFromMultiItem();
- mActionItem->setIncidence( newInc );
- bool success = mChanger->addIncidence( newInc, this );
- emit enableAgendaUpdate( true );
- if ( success ) {
- mChanger->changeIncidence( oldIncSaved, oldInc );
- }
- } else {
- KMessageBox::sorry( this, i18n("Unable to add the exception item to the "
- "calendar. No change will be done."), i18n("Error Occurred") );
- }
- delete oldIncSaved;
- break; }
- case KMessageBox::No/*Future*/: { // All future occurrences
- // Dissociate this occurrence:
- // create clone of event, set relation to old event, set cloned event
- // for mActionItem, add recurrence end date to old event, changeIncidence
- // for the old event, adjust the recurrence for the new copy and then just
- // go on with the newly adjusted mActionItem and let the usual code take
- // care of the new time!
- modify = true;
- multiModify = true;
- emit startMultiModify( i18n("Split future recurrences") );
- Incidence* oldInc = mActionItem->incidence();
- Incidence* oldIncSaved = mActionItem->incidence()->clone();
- newInc = mCalendar->dissociateOccurrence(
- oldInc, mActionItem->itemDate(), false );
- if ( newInc ) {
- emit enableAgendaUpdate( false );
- mActionItem->dissociateFromMultiItem();
- mActionItem->setIncidence( newInc );
- bool success = mChanger->addIncidence( newInc, this );
- emit enableAgendaUpdate( true );
- if ( success ) {
- mChanger->changeIncidence( oldIncSaved, oldInc );
- }
- } else {
- KMessageBox::sorry( this, i18n("Unable to add the future items to the "
- "calendar. No change will be done."), i18n("Error Occurred") );
- }
- delete oldIncSaved;
- break; }
- default:
- modify = false;
- mActionItem->resetMove();
- placeSubCells( mActionItem );
- }
- }
+ Incidence* oldIncSaved = inc->clone();
+ KOGlobals::WhichOccurrences chosenOption;
+ incToChange = mCalendarView->singleOccurrenceOrAll( inc,
+ KOGlobals::EDIT,
+ chosenOption,
+ mActionItem->itemDate() );
+
+ if ( chosenOption == KOGlobals::ONLY_THIS_ONE ||
+ chosenOption == KOGlobals::ONLY_FUTURE ) {
+
+ // Store modification information in case it is needed to recreate the changes with a new actionitem...
+ int mai_xl = mActionItem->cellXLeft();
+ int mai_xr = mActionItem->cellXRight();
+ int mai_yt = mActionItem->cellYTop();
+ int mai_yb = mActionItem->cellYBottom();
+
+ multiModify = true;
+ enableAgendaUpdate( false );
+
+ mChanger->addIncidence( incToChange, mResPair.first, mResPair.second, this );
+ enableAgendaUpdate( true );
+ KOGlobals::WhatChanged wc = chosenOption == KOGlobals::ONLY_THIS_ONE ?
+ KOGlobals::RECURRENCE_MODIFIED_ONE_ONLY :
+ KOGlobals::RECURRENCE_MODIFIED_ALL_FUTURE;
+
+ mChanger->changeIncidence( oldIncSaved, inc, wc, this );
- if ( modify ) {
- if ( multiModify ) {
// mActionItem does not exist any more, seeing as we just got done deleting it
// (by deleting/replacing the original incidence it was created from through
// user modification of said incidence) above!
@@ -1146,7 +1134,7 @@ void KOAgenda::endItemAction()
KOAgendaItem *koai_insertedItem;
for ( koai_insertedItem = mItems.first(); koai_insertedItem; koai_insertedItem = mItems.next() ) {
- if (koai_insertedItem->incidence() == newInc) {
+ if (koai_insertedItem->incidence() == incToChange) {
selectItem( koai_insertedItem );
mSelectedItem->startMove();
mSelectedItem->setCellY(mai_yt, mai_yb);
@@ -1157,15 +1145,12 @@ void KOAgenda::endItemAction()
}
}
-// mActionItem->startMove();
-// mActionItem->setCellY(mai_yt, mai_yb);
-// mActionItem->setCellX(mai_xl, mai_xr);
-// mActionItem->endMove();
+ mActionItem->dissociateFromMultiItem();
+ mActionItem->setIncidence( incToChange );
}
}
- if ( modify ) {
-// if ( !multiModify ) {
+ if ( incToChange ) {
mActionItem->endMove();
KOAgendaItem *placeItem = mActionItem->firstMultiItem();
if ( !placeItem ) {
@@ -1187,17 +1172,27 @@ void KOAgenda::endItemAction()
// Notify about change
// the agenda view will apply the changes to the actual Incidence*!
+ mChanger->endChange( inc, mResPair.first, mResPair.second );
emit itemModified( modif );
-// }
+ } else {
+
+ mActionItem->resetMove();
+ placeSubCells( mActionItem );
+
+ // the item was moved, but not further modified, since it's not recurring
+ // make sure the view updates anyhow, with the right item
+ mChanger->endChange( inc, mResPair.first, mResPair.second );
+ emit itemModified( mActionItem );
}
- // FIXME: If the change failed, we need to update the view!
- mChanger->endChange( inc );
}
mActionItem = 0;
+ mResPair = qMakePair( static_cast<ResourceCalendar *>( 0 ), TQString() );
mItemMoved = false;
- if ( multiModify ) emit endMultiModify();
+ if ( multiModify ) {
+ emit endMultiModify();
+ }
kdDebug(5850) << "KOAgenda::endItemAction() done" << endl;
}
@@ -1280,7 +1275,7 @@ void KOAgenda::placeAgendaItem( KOAgendaItem *item, double subCellWidth )
TQPoint pt = gridToContents( TQPoint( item->cellXLeft(), item->cellYTop() ) );
// right lower corner
TQPoint pt1 = gridToContents( TQPoint( item->cellXLeft() + item->cellWidth(),
- item->cellYBottom()+1 ) );
+ item->cellYBottom()+1 ) );
double subCellPos = item->subCell() * subCellWidth;
@@ -1594,23 +1589,16 @@ void KOAgenda::setStartTime( const TQTime &startHour )
Insert KOAgendaItem into agenda.
*/
KOAgendaItem *KOAgenda::insertItem( Incidence *incidence, const TQDate &qd, int X,
- int YTop, int YBottom )
+ int YTop, int YBottom, int itemPos, int itemCount )
{
-#if 0
- kdDebug(5850) << "KOAgenda::insertItem:" << incidence->summary() << "-"
- << qd.toString() << " ;top, bottom:" << YTop << "," << YBottom
- << endl;
-#endif
-
if ( mAllDayMode ) {
kdDebug(5850) << "KOAgenda: calling insertItem in all-day mode is illegal." << endl;
return 0;
}
-
mActionType = NOP;
- KOAgendaItem *agendaItem = new KOAgendaItem( incidence, qd, viewport() );
+ KOAgendaItem *agendaItem = new KOAgendaItem( mCalendar, incidence, qd, viewport(), itemPos, itemCount );
connect( agendaItem, TQT_SIGNAL( removeAgendaItem( KOAgendaItem * ) ),
TQT_SLOT( removeAgendaItem( KOAgendaItem * ) ) );
connect( agendaItem, TQT_SIGNAL( showAgendaItem( KOAgendaItem * ) ),
@@ -1655,7 +1643,7 @@ KOAgendaItem *KOAgenda::insertAllDayItem( Incidence *event, const TQDate &qd,
mActionType = NOP;
- KOAgendaItem *agendaItem = new KOAgendaItem( event, qd, viewport() );
+ KOAgendaItem *agendaItem = new KOAgendaItem( mCalendar, event, qd, viewport(), 1, 1 );
connect( agendaItem, TQT_SIGNAL( removeAgendaItem( KOAgendaItem* ) ),
TQT_SLOT( removeAgendaItem( KOAgendaItem* ) ) );
connect( agendaItem, TQT_SIGNAL( showAgendaItem( KOAgendaItem* ) ),
@@ -1683,10 +1671,10 @@ KOAgendaItem *KOAgenda::insertAllDayItem( Incidence *event, const TQDate &qd,
}
-void KOAgenda::insertMultiItem (Event *event,const TQDate &qd,int XBegin,int XEnd,
- int YTop,int YBottom)
+void KOAgenda::insertMultiItem( Event *event, const TQDate &qd, int XBegin, int XEnd,
+ int YTop, int YBottom )
{
- if (mAllDayMode) {
+ if ( mAllDayMode ) {
kdDebug(5850) << "KOAgenda: calling insertMultiItem in all-day mode is illegal." << endl;
return;
}
@@ -1698,40 +1686,50 @@ void KOAgenda::insertMultiItem (Event *event,const TQDate &qd,int XBegin,int XEn
int count = 0;
KOAgendaItem *current = 0;
TQPtrList<KOAgendaItem> multiItems;
- int visibleCount = mSelectedDates.first().daysTo(mSelectedDates.last());
+ const int visibleCount = mSelectedDates.first().daysTo( mSelectedDates.last() );
for ( cellX = XBegin; cellX <= XEnd; ++cellX ) {
++count;
//Only add the items that are visible.
- if( cellX >=0 && cellX <= visibleCount ) {
- if ( cellX == XBegin ) cellYTop = YTop;
- else cellYTop = 0;
- if ( cellX == XEnd ) cellYBottom = YBottom;
- else cellYBottom = rows() - 1;
+ if( cellX >= 0 && cellX <= visibleCount ) {
+ if ( cellX == XBegin ) {
+ cellYTop = YTop;
+ } else {
+ cellYTop = 0;
+ }
+
+ if ( cellX == XEnd ) {
+ cellYBottom = YBottom;
+ } else {
+ cellYBottom = rows() - 1;
+ }
+
newtext = TQString("(%1/%2): ").arg( count ).arg( width );
newtext.append( event->summary() );
- current = insertItem( event, qd, cellX, cellYTop, cellYBottom );
+ current = insertItem( event, qd, cellX, cellYTop, cellYBottom, count, width );
current->setText( newtext );
multiItems.append( current );
}
}
-
- KOAgendaItem *next = 0;
- KOAgendaItem *prev = 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, prev, next, setLast);
- prev=current;
- current = next;
+ TQPtrList<KOAgendaItem>::iterator it = multiItems.begin();
+ TQPtrList<KOAgendaItem>::iterator e = multiItems.end();
+
+ if ( it != e ) { // .first asserts if the list is empty
+ KOAgendaItem *first = multiItems.first();
+ KOAgendaItem *last = multiItems.last();
+ KOAgendaItem *prev = 0, *next = 0;
+
+ while ( it != e ) {
+ KOAgendaItem *item = *it;
+ ++it;
+ next = ( it == e ) ? 0 : (*it);
+ if ( item ) {
+ item->setMultiItem( ( item == first ) ? 0 : first,
+ prev, next,
+ ( item == last ) ? 0 : last );
+ }
+ prev = item;
+ }
}
marcus_bains();
@@ -1760,11 +1758,15 @@ void KOAgenda::removeIncidence( Incidence *incidence )
void KOAgenda::showAgendaItem( KOAgendaItem *agendaItem )
{
- if ( !agendaItem ) return;
+ if ( !agendaItem ) {
+ return;
+ }
+
agendaItem->hide();
addChild( agendaItem );
- if ( !mItems.containsRef( agendaItem ) )
+ if ( !mItems.containsRef( agendaItem ) ) {
mItems.append( agendaItem );
+ }
placeSubCells( agendaItem );
agendaItem->show();
@@ -1777,8 +1779,9 @@ bool KOAgenda::removeAgendaItem( KOAgendaItem *item )
KOAgendaItem *thisItem = item;
TQPtrList<KOAgendaItem> conflictItems = thisItem->conflictItems();
removeChild( thisItem );
+
int pos = mItems.find( thisItem );
- if ( pos>=0 ) {
+ if ( pos >= 0 ) {
mItems.take( pos );
taken = true;
}
@@ -1843,23 +1846,24 @@ void KOAgenda::resizeEvent ( TQResizeEvent *ev )
void KOAgenda::resizeAllContents()
{
double subCellWidth;
- KOAgendaItem *item;
- if (mAllDayMode) {
- for ( item=mItems.first(); item != 0; item=mItems.next() ) {
- subCellWidth = calcSubCellWidth( item );
- placeAgendaItem( item, subCellWidth );
- }
- } else {
- for ( item=mItems.first(); item != 0; item=mItems.next() ) {
- subCellWidth = calcSubCellWidth( item );
- placeAgendaItem( item, subCellWidth );
+ if ( mItems.count() > 0 ) {
+ KOAgendaItem *item;
+ if (mAllDayMode) {
+ for ( item=mItems.first(); item != 0; item=mItems.next() ) {
+ subCellWidth = calcSubCellWidth( item );
+ placeAgendaItem( item, subCellWidth );
+ }
+ } else {
+ for ( item=mItems.first(); item != 0; item=mItems.next() ) {
+ subCellWidth = calcSubCellWidth( item );
+ placeAgendaItem( item, subCellWidth );
+ }
}
}
checkScrollBoundaries();
marcus_bains();
}
-
void KOAgenda::scrollUp()
{
scrollBy(0,-mScrollOffset);
@@ -1886,15 +1890,23 @@ int KOAgenda::minimumWidth() const
void KOAgenda::updateConfig()
{
double oldGridSpacingY = mGridSpacingY;
+
mDesiredGridSpacingY = KOPrefs::instance()->mHourSize;
- // make sure that there are not more than 24 per day
- mGridSpacingY = (double)height()/(double)mRows;
- if (mGridSpacingY<mDesiredGridSpacingY) mGridSpacingY=mDesiredGridSpacingY;
+ if ( mDesiredGridSpacingY < 4 || mDesiredGridSpacingY > 30 ) {
+ mDesiredGridSpacingY = 10;
+ }
+
+ // make sure that there are not more than 24 per day
+ mGridSpacingY = (double)height() / (double)mRows;
+ if ( mGridSpacingY < mDesiredGridSpacingY ) {
+ mGridSpacingY = mDesiredGridSpacingY;
+ }
//can be two doubles equal?, it's better to compare them with an epsilon
- if ( fabs( oldGridSpacingY - mGridSpacingY ) > 0.1 )
+ if ( fabs( oldGridSpacingY - mGridSpacingY ) > 0.1 ) {
resizeContents( int( mGridSpacingX * mColumns ),
- int( mGridSpacingY * mRows ) );
+ int( mGridSpacingY * mRows ) );
+ }
calculateWorkingHours();
@@ -1941,7 +1953,9 @@ int KOAgenda::visibleContentsYMax()
void KOAgenda::deselectItem()
{
- if (mSelectedItem.isNull()) return;
+ if ( mSelectedItem.isNull() ) {
+ return;
+ }
mSelectedItem->select(false);
mSelectedItem = 0;
}
@@ -1951,15 +1965,14 @@ void KOAgenda::selectItem(KOAgendaItem *item)
if ((KOAgendaItem *)mSelectedItem == item) return;
deselectItem();
if (item == 0) {
- emit incidenceSelected( 0 );
+ emit incidenceSelected( 0, TQDate() );
return;
}
mSelectedItem = item;
mSelectedItem->select();
- Incidence *incidence = mSelectedItem->incidence();
- assert( incidence );
- mSelectedUid = incidence->uid();
- emit incidenceSelected( incidence );
+ assert( mSelectedItem->incidence() );
+ mSelectedUid = mSelectedItem->incidence()->uid();
+ emit incidenceSelected( mSelectedItem->incidence(), mSelectedItem->itemDate() );
}
void KOAgenda::selectItemByUID( const TQString& uid )
diff --git a/korganizer/koagenda.h b/korganizer/koagenda.h
index a6d06d00..223ea1aa 100644
--- a/korganizer/koagenda.h
+++ b/korganizer/koagenda.h
@@ -29,6 +29,7 @@
#include <tqguardedptr.h>
#include <libkcal/incidencebase.h>
+#include "calendarview.h"
class TQPopupMenu;
class TQTime;
@@ -37,44 +38,46 @@ class KConfig;
class KOAgenda;
class KOAgendaItem;
-using namespace KOrg;
namespace KOrg {
-class IncidenceChangerBase;
+ class IncidenceChangerBase;
}
+using namespace KOrg;
-using namespace KCal;
namespace KCal {
-class Event;
-class Todo;
-class Calendar;
+ class Event;
+ class Todo;
+ class Calendar;
}
+using namespace KCal;
-class MarcusBains : public TQFrame {
- Q_OBJECT
+class MarcusBains : public TQFrame
+{
+ Q_OBJECT
public:
MarcusBains( KOAgenda *agenda = 0, const char *name = 0 );
+ void updateLocationRecalc( bool recalculate = false );
virtual ~MarcusBains();
public slots:
- void updateLocation( bool recalculate = false );
+ void updateLocation();
private:
int todayColumn();
TQTimer *minutes;
TQLabel *mTimeBox;
KOAgenda *agenda;
- TQTime oldTime;
- int oldToday;
+ TQTime mOldTime;
+ int mOldToday;
};
-
-class KOAgenda : public QScrollView
+class KOAgenda : public TQScrollView
{
- Q_OBJECT
+ Q_OBJECT
public:
- KOAgenda ( int columns, int rows, int columnSize, TQWidget *parent=0,
- const char *name = 0, WFlags f = 0 );
- KOAgenda ( int columns, TQWidget *parent = 0,
+ KOAgenda ( int columns, int rows, int columnSize, CalendarView *calendarView,
+ TQWidget *parent=0, const char *name = 0, WFlags f = 0 );
+
+ KOAgenda ( int columns, CalendarView *calendarView, TQWidget *parent = 0,
const char *name = 0, WFlags f = 0 );
virtual ~KOAgenda();
@@ -103,7 +106,7 @@ class KOAgenda : public QScrollView
void setStartTime( const TQTime &startHour );
KOAgendaItem *insertItem ( Incidence *incidence, const TQDate &qd, int X, int YTop,
- int YBottom );
+ int YBottom, int itemPos, int itemCount );
KOAgendaItem *insertAllDayItem ( Incidence *event, const TQDate &qd, int XBegin,
int XEnd );
void insertMultiItem ( Event *event, const TQDate &qd, int XBegin, int XEnd,
@@ -171,18 +174,18 @@ class KOAgenda : public QScrollView
void showAgendaItem( KOAgendaItem *item );
signals:
- void newEventSignal();
+ void newEventSignal( ResourceCalendar *res, const TQString &subResource );
void newTimeSpanSignal( const TQPoint &, const TQPoint & );
void newStartSelectSignal();
- void showIncidenceSignal( Incidence * );
- void editIncidenceSignal( Incidence * );
+ void showIncidenceSignal( Incidence *, const TQDate & );
+ void editIncidenceSignal( Incidence *, const TQDate & );
void deleteIncidenceSignal( Incidence * );
- void showIncidencePopupSignal( Incidence *, const TQDate &);
+ void showIncidencePopupSignal( Calendar *, Incidence *, const TQDate &);
void showNewEventPopupSignal();
void itemModified( KOAgendaItem *item );
- void incidenceSelected( Incidence * );
+ void incidenceSelected( Incidence *, const TQDate & );
void startMultiModify( const TQString & );
void endMultiModify();
@@ -343,6 +346,7 @@ class KOAgenda : public QScrollView
// The KOAgendaItem, which is being moved/resized
TQGuardedPtr<KOAgendaItem> mActionItem;
+ QPair<ResourceCalendar *, TQString> mResPair;
// Currently selected item
TQGuardedPtr<KOAgendaItem> mSelectedItem;
@@ -373,6 +377,8 @@ class KOAgenda : public QScrollView
bool mReturnPressed;
KOrg::IncidenceChangerBase *mChanger;
+
+ CalendarView *mCalendarView;
};
#endif // KOAGENDA_H
diff --git a/korganizer/koagendaitem.cpp b/korganizer/koagendaitem.cpp
index 629f59c3..de1f4ef8 100644
--- a/korganizer/koagendaitem.cpp
+++ b/korganizer/koagendaitem.cpp
@@ -63,12 +63,16 @@ TQPixmap *KOAgendaItem::organizerPxmp = 0;
//--------------------------------------------------------------------------
-KOAgendaItem::KOAgendaItem( Incidence *incidence, const TQDate &qd, TQWidget *parent,
+KOAgendaItem::KOAgendaItem( Calendar *calendar, Incidence *incidence,
+ const TQDate &qd, TQWidget *parent,
+ int itemPos, int itemCount,
const char *name, WFlags f ) :
- TQWidget( parent, name, f ), mIncidence( incidence ), mDate( qd ),
+ TQWidget( parent, name, f ), mCalendar( calendar ), mIncidence( incidence ), mDate( qd ),
mLabelText( mIncidence->summary() ), mIconAlarm( false ),
mIconRecur( false ), mIconReadonly( false ), mIconReply( false ),
mIconGroup( false ), mIconGroupTentative( false ), mIconOrganizer( false ),
+ mSpecialEvent( false ),
+ mItemPos( itemPos ), mItemCount( itemCount ),
mMultiItemInfo( 0 ), mStartMoveInfo( 0 )
{
setBackgroundMode( Qt::NoBackground );
@@ -83,7 +87,7 @@ KOAgendaItem::KOAgendaItem( Incidence *incidence, const TQDate &qd, TQWidget *pa
mSelected = true;
select( false );
- KOIncidenceToolTip::add( this, incidence, toolTipGroup() );
+ KOIncidenceToolTip::add( this, mCalendar, incidence, mDate, toolTipGroup() );
setAcceptDrops( true );
}
@@ -93,7 +97,7 @@ void KOAgendaItem::updateIcons()
mIconReadonly = mIncidence->isReadOnly();
mIconRecur = mIncidence->doesRecur();
mIconAlarm = mIncidence->isAlarmEnabled();
- if ( mIncidence->attendeeCount() > 0 ) {
+ if ( mIncidence->attendeeCount() > 1 ) {
if ( KOPrefs::instance()->thatIsMe( mIncidence->organizer().email() ) ) {
mIconReply = false;
mIconGroup = false;
@@ -171,7 +175,6 @@ bool KOAgendaItem::setIncidence( Incidence *i )
return true;
}
-
/*
Return height of item in units of agenda cells
*/
@@ -217,10 +220,12 @@ void KOAgendaItem::setCellY( int YTop, int YBottom )
mCellYBottom = YBottom;
}
-void KOAgendaItem::setMultiItem(KOAgendaItem *first, KOAgendaItem *prev,
- KOAgendaItem *next, KOAgendaItem *last)
+void KOAgendaItem::setMultiItem( KOAgendaItem *first, KOAgendaItem *prev,
+ KOAgendaItem *next, KOAgendaItem *last )
{
- if (!mMultiItemInfo) mMultiItemInfo=new MultiItemInfo;
+ if ( !mMultiItemInfo ) {
+ mMultiItemInfo = new MultiItemInfo;
+ }
mMultiItemInfo->mFirstMultiItem = first;
mMultiItemInfo->mPrevMultiItem = prev;
mMultiItemInfo->mNextMultiItem = next;
@@ -575,18 +580,16 @@ void KOAgendaItem::dropEvent( TQDropEvent *e )
}
#ifndef KORG_NOKABC
- TQString vcards;
- KABC::VCardConverter converter;
-
- KVCardDrag::decode( e, vcards );
- KABC::Addressee::List list = converter.parseVCards( vcards );
- KABC::Addressee::List::Iterator it;
- for ( it = list.begin(); it != list.end(); ++it ) {
- TQString em( (*it).fullEmail() );
- if (em.isEmpty()) {
- em=(*it).realName();
+ KABC::Addressee::List list;
+ if ( KVCardDrag::decode( e, list ) ) {
+ KABC::Addressee::List::Iterator it;
+ for ( it = list.begin(); it != list.end(); ++it ) {
+ TQString em( (*it).fullEmail() );
+ if ( em.isEmpty() ) {
+ em = (*it).realName();
+ }
+ addAttendee( em );
}
- addAttendee( em );
}
#else
if( decoded ) {
@@ -665,11 +668,21 @@ static void conditionalPaint( TQPainter *p, bool cond, int &x, int ft,
void KOAgendaItem::paintEventIcon( TQPainter *p, int &x, int ft )
{
if ( !mIncidence ) return;
- static const TQPixmap eventPxmp =
- KOGlobals::self()->smallIcon( "appointment" );
- if ( mIncidence->type() != "Event" )
- return;
- conditionalPaint( p, true, x, ft, eventPxmp );
+
+ if ( mIncidence->type() == "Event" ) {
+ TQPixmap eventPxmp;
+ if ( mIncidence->customProperty( "KABC", "BIRTHDAY" ) == "YES" ) {
+ mSpecialEvent = true;
+ if ( mIncidence->customProperty( "KABC", "ANNIVERSARY" ) == "YES" ) {
+ eventPxmp = KOGlobals::self()->smallIcon( "calendaranniversary" );
+ } else {
+ eventPxmp = KOGlobals::self()->smallIcon( "calendarbirthday" );
+ }
+ conditionalPaint( p, true, x, ft, eventPxmp );
+ }
+ // per kolab/issue4349 we don't draw a regular appointment icon (to save space)
+ }
+
}
void KOAgendaItem::paintTodoIcon( TQPainter *p, int &x, int ft )
@@ -702,9 +715,11 @@ void KOAgendaItem::paintIcons( TQPainter *p, int &x, int ft )
{
paintEventIcon( p, x, ft );
paintTodoIcon( p, x, ft );
- paintAlarmIcon( p, x, ft );
- conditionalPaint( p, mIconRecur, x, ft, *recurPxmp );
- conditionalPaint( p, mIconReadonly, x, ft, *readonlyPxmp );
+ if ( !mSpecialEvent ) {
+ paintAlarmIcon( p, x, ft );
+ }
+ conditionalPaint( p, mIconRecur && !mSpecialEvent, x, ft, *recurPxmp );
+ conditionalPaint( p, mIconReadonly && !mSpecialEvent, x, ft, *readonlyPxmp );
conditionalPaint( p, mIconReply, x, ft, *replyPxmp );
conditionalPaint( p, mIconGroup, x, ft, *groupPxmp );
conditionalPaint( p, mIconGroupTentative, x, ft, *groupPxmpTentative );
@@ -762,7 +777,7 @@ void KOAgendaItem::paintEvent( TQPaintEvent *ev )
TQStringList categories = mIncidence->categories();
TQString cat = categories.first();
if (cat.isEmpty())
- categoryColor = KOPrefs::instance()->mEventColor;
+ categoryColor = KOPrefs::instance()->unsetCategoryColor();
else
categoryColor = *(KOPrefs::instance()->categoryColor(cat));
@@ -770,9 +785,6 @@ void KOAgendaItem::paintEvent( TQPaintEvent *ev )
if ( !resourceColor.isValid() )
resourceColor = categoryColor;
- if (!KOPrefs::instance()->hasCategoryColor(cat))
- categoryColor = resourceColor;
-
TQColor frameColor;
if ( KOPrefs::instance()->agendaViewColors() == KOPrefs::ResourceOnly ||
KOPrefs::instance()->agendaViewColors() == KOPrefs::CategoryInsideResourceOutside ) {
@@ -790,6 +802,16 @@ void KOAgendaItem::paintEvent( TQPaintEvent *ev )
}
}
+ if ( cat.isEmpty() &&
+ KOPrefs::instance()->agendaViewColors() == KOPrefs::ResourceInsideCategoryOutside ) {
+ frameColor = bgColor;
+ }
+
+ if ( cat.isEmpty() &&
+ KOPrefs::instance()->agendaViewColors() == KOPrefs::CategoryInsideResourceOutside ) {
+ bgColor = frameColor;
+ }
+
if ( mSelected ) {
frameColor = TQColor( 85 + frameColor.red() * 2/3,
85 + frameColor.green() * 2/3,
diff --git a/korganizer/koagendaitem.h b/korganizer/koagendaitem.h
index fc774dd1..f1559442 100644
--- a/korganizer/koagendaitem.h
+++ b/korganizer/koagendaitem.h
@@ -34,6 +34,7 @@ class TQDragEnterEvent;
class TQDropEvent;
namespace KCal {
+class Calendar;
class Incidence;
}
using namespace KCal;
@@ -75,8 +76,10 @@ class KOAgendaItem : public TQWidget, public KOrg::CellItem
{
Q_OBJECT
public:
- KOAgendaItem(Incidence *incidence, const TQDate &qd, TQWidget *parent, const char *name=0,
- WFlags f=0 );
+ KOAgendaItem( Calendar *calendar, Incidence *incidence, const TQDate &qd,
+ TQWidget *parent,
+ int itemPos, int itemCount,
+ const char *name = 0, WFlags f = 0 );
int cellXLeft() const { return mCellXLeft; }
int cellXRight() const { return mCellXRight; }
@@ -85,6 +88,9 @@ class KOAgendaItem : public TQWidget, public KOrg::CellItem
int cellHeight() const;
int cellWidth() const;
+ int itemPos() const { return mItemPos; }
+ int itemCount() const { return mItemCount; }
+
void setCellXY(int X, int YTop, int YBottom);
void setCellY(int YTop, int YBottom);
void setCellX(int XLeft, int XRight);
@@ -173,15 +179,19 @@ class KOAgendaItem : public TQWidget, public KOrg::CellItem
private:
int mCellXLeft, mCellXRight;
int mCellYTop, mCellYBottom;
- int mSubCell; // subcell number of this item
- int mSubCells; // Total number of subcells in cell of this item
+ Calendar *mCalendar;
Incidence *mIncidence; // corresponding event or todo
TQDate mDate; //date this events occurs (for recurrence)
TQString mLabelText;
bool mIconAlarm, mIconRecur, mIconReadonly;
bool mIconReply, mIconGroup, mIconGroupTentative;
- bool mIconOrganizer;
+ bool mIconOrganizer, mSpecialEvent;
+
+ // For incidences that expand through more than 1 day
+ // Will be 1 for single day incidences
+ int mItemPos;
+ int mItemCount;
// Multi item pointers
MultiItemInfo* mMultiItemInfo;
diff --git a/korganizer/koagendaview.cpp b/korganizer/koagendaview.cpp
index e45493ab..c60546f7 100644
--- a/korganizer/koagendaview.cpp
+++ b/korganizer/koagendaview.cpp
@@ -152,6 +152,7 @@ void KOAlternateLabel::useShortText()
TQLabel::setText( mShortText );
TQToolTip::remove( this );
TQToolTip::add( this, mExtensiveText );
+ update(); // for kolab/issue4350
}
void KOAlternateLabel::useLongText()
@@ -160,6 +161,7 @@ void KOAlternateLabel::useLongText()
TQLabel::setText( mLongText );
TQToolTip::remove( this );
TQToolTip::add( this, mExtensiveText );
+ update(); // for kolab/issue4350
}
void KOAlternateLabel::useExtensiveText()
@@ -167,7 +169,8 @@ void KOAlternateLabel::useExtensiveText()
mTextTypeFixed = true;
TQLabel::setText( mExtensiveText );
TQToolTip::remove( this );
- TQToolTip::hide();
+ TQToolTip::add( this, "" );
+ update(); // for kolab/issue4350
}
void KOAlternateLabel::useDefaultText()
@@ -176,27 +179,55 @@ void KOAlternateLabel::useDefaultText()
squeezeTextToLabel();
}
+KOAlternateLabel::TextType KOAlternateLabel::largestFittingTextType() const
+{
+ TQFontMetrics fm( fontMetrics() );
+ const int labelWidth = size().width();
+ const int longTextWidth = fm.width( mLongText );
+ const int extensiveTextWidth = fm.width( mExtensiveText );
+ if ( extensiveTextWidth <= labelWidth )
+ return Extensive;
+ else if ( longTextWidth <= labelWidth )
+ return Long;
+ else
+ return Short;
+}
+
+void KOAlternateLabel::setFixedType( TextType type )
+{
+ switch ( type )
+ {
+ case Extensive: useExtensiveText(); break;
+ case Long: useLongText(); break;
+ case Short: useShortText(); break;
+ }
+}
+
void KOAlternateLabel::squeezeTextToLabel()
{
- if (mTextTypeFixed) return;
-
- TQFontMetrics fm(fontMetrics());
- int labelWidth = size().width();
- int textWidth = fm.width(mLongText);
- int longTextWidth = fm.width(mExtensiveText);
- if (longTextWidth <= labelWidth) {
- TQLabel::setText( mExtensiveText );
- TQToolTip::remove( this );
- TQToolTip::hide();
- } else if (textWidth <= labelWidth) {
- TQLabel::setText( mLongText );
- TQToolTip::remove( this );
- TQToolTip::add( this, mExtensiveText );
- } else {
- TQLabel::setText( mShortText );
- TQToolTip::remove( this );
- TQToolTip::add( this, mExtensiveText );
+ if ( mTextTypeFixed )
+ return;
+
+ const TextType type = largestFittingTextType();
+ switch ( type )
+ {
+ case Extensive:
+ TQLabel::setText( mExtensiveText );
+ TQToolTip::remove( this );
+ TQToolTip::add( this, "" );
+ break;
+ case Long:
+ TQLabel::setText( mLongText );
+ TQToolTip::remove( this );
+ TQToolTip::add( this, mExtensiveText );
+ break;
+ case Short:
+ TQLabel::setText( mShortText );
+ TQToolTip::remove( this );
+ TQToolTip::add( this, mExtensiveText );
+ break;
}
+ update(); // for kolab/issue4350
}
void KOAlternateLabel::resizeEvent( TQResizeEvent * )
@@ -211,22 +242,21 @@ TQSize KOAlternateLabel::minimumSizeHint() const
return sh;
}
-void KOAlternateLabel::setText( const TQString &text ) {
- mLongText = text;
- squeezeTextToLabel();
-}
-
-
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
-KOAgendaView::KOAgendaView(Calendar *cal,TQWidget *parent,const char *name, bool isSideBySide ) :
- KOrg::AgendaView (cal,parent,name), mExpandButton( 0 ), mAllowAgendaUpdate( true ),
+KOAgendaView::KOAgendaView( Calendar *cal,
+ CalendarView *calendarView,
+ TQWidget *parent,
+ const char *name,
+ bool isSideBySide ) :
+ KOrg::AgendaView (cal, parent,name), mExpandButton( 0 ),
+ mAllowAgendaUpdate( true ),
mUpdateItem( 0 ),
- mResource( 0 ),
mIsSideBySide( isSideBySide ),
- mPendingChanges( true )
+ mPendingChanges( true ),
+ mAreDatesInitialized( false )
{
mSelectedDates.append(TQDate::currentDate());
@@ -291,7 +321,8 @@ KOAgendaView::KOAgendaView(Calendar *cal,TQWidget *parent,const char *name, bool
label->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::WordBreak );
}
- mAllDayAgenda = new KOAgenda(1,mAllDayFrame);
+ mAllDayAgenda = new KOAgenda( 1, calendarView, mAllDayFrame );
+ mAllDayAgenda->setCalendar( calendar() );
TQWidget *dummyAllDayRight = new TQWidget(mAllDayFrame);
// Create agenda frame
@@ -312,7 +343,8 @@ KOAgendaView::KOAgendaView(Calendar *cal,TQWidget *parent,const char *name, bool
agendaLayout->addWidget(mTimeLabels,1,0);
// Create agenda
- mAgenda = new KOAgenda(1,96,KOPrefs::instance()->mHourSize,agendaFrame);
+ mAgenda = new KOAgenda( 1, 96, KOPrefs::instance()->mHourSize, calendarView, agendaFrame );
+ mAgenda->setCalendar( calendar() );
agendaLayout->addMultiCellWidget(mAgenda,1,1,1,2);
agendaLayout->setColStretch(1,1);
@@ -330,7 +362,7 @@ KOAgendaView::KOAgendaView(Calendar *cal,TQWidget *parent,const char *name, bool
// Update widgets to reflect user preferences
// updateConfig();
- createDayLabels();
+ createDayLabels( true );
if ( !isSideBySide ) {
// these blank widgets make the All Day Event box line up with the agenda
@@ -363,17 +395,13 @@ KOAgendaView::KOAgendaView(Calendar *cal,TQWidget *parent,const char *name, bool
connect( mAgenda, TQT_SIGNAL(upperYChanged(int)),
TQT_SLOT(updateEventIndicatorBottom(int)));
- connectAgenda( mAgenda, mAgendaPopup, mAllDayAgenda );
- connectAgenda( mAllDayAgenda, mAllDayAgendaPopup, mAgenda);
+ if ( !readOnly() ) {
+ connectAgenda( mAgenda, mAgendaPopup, mAllDayAgenda );
+ connectAgenda( mAllDayAgenda, mAllDayAgendaPopup, mAgenda);
+ }
- if ( cal )
+ if ( cal ) {
cal->registerObserver( this );
-
- CalendarResources *calres = dynamic_cast<CalendarResources*>( cal );
- if ( calres ) {
- connect( calres, TQT_SIGNAL(signalResourceAdded(ResourceCalendar *)), TQT_SLOT(resourcesChanged()) );
- connect( calres, TQT_SIGNAL(signalResourceModified( ResourceCalendar *)), TQT_SLOT(resourcesChanged()) );
- connect( calres, TQT_SIGNAL(signalResourceDeleted(ResourceCalendar *)), TQT_SLOT(resourcesChanged()) );
}
}
@@ -389,52 +417,53 @@ KOAgendaView::~KOAgendaView()
void KOAgendaView::connectAgenda( KOAgenda *agenda, TQPopupMenu *popup,
KOAgenda *otherAgenda )
{
- connect( agenda, TQT_SIGNAL( showIncidencePopupSignal( Incidence *, const TQDate & ) ),
- popup, TQT_SLOT( showIncidencePopup( Incidence *, const TQDate & ) ) );
+ connect( agenda, TQT_SIGNAL(showIncidencePopupSignal(Calendar *,Incidence *,const TQDate &)),
+ popup, TQT_SLOT(showIncidencePopup(Calendar *,Incidence *,const TQDate &)) );
- connect( agenda, TQT_SIGNAL( showNewEventPopupSignal() ),
- TQT_SLOT( showNewEventPopup() ) );
+ connect( agenda, TQT_SIGNAL(showNewEventPopupSignal()),
+ TQT_SLOT(showNewEventPopup()) );
- agenda->setCalendar( calendar() );
// Create/Show/Edit/Delete Event
- connect( agenda, TQT_SIGNAL( newEventSignal() ), TQT_SIGNAL( newEventSignal() ) );
-
- connect( agenda, TQT_SIGNAL( newStartSelectSignal() ),
- otherAgenda, TQT_SLOT( clearSelection() ) );
- connect( agenda, TQT_SIGNAL( newStartSelectSignal() ),
- TQT_SIGNAL( timeSpanSelectionChanged()) );
-
- connect( agenda, TQT_SIGNAL( editIncidenceSignal( Incidence * ) ),
- TQT_SIGNAL( editIncidenceSignal( Incidence * ) ) );
- connect( agenda, TQT_SIGNAL( showIncidenceSignal( Incidence * ) ),
- TQT_SIGNAL( showIncidenceSignal( Incidence * ) ) );
- connect( agenda, TQT_SIGNAL( deleteIncidenceSignal( Incidence * ) ),
- TQT_SIGNAL( deleteIncidenceSignal( Incidence * ) ) );
-
- connect( agenda, TQT_SIGNAL( startMultiModify( const TQString & ) ),
- TQT_SIGNAL( startMultiModify( const TQString & ) ) );
- connect( agenda, TQT_SIGNAL( endMultiModify() ),
- TQT_SIGNAL( endMultiModify() ) );
-
- connect( agenda, TQT_SIGNAL( itemModified( KOAgendaItem * ) ),
- TQT_SLOT( updateEventDates( KOAgendaItem * ) ) );
- connect( agenda, TQT_SIGNAL( enableAgendaUpdate( bool ) ),
- TQT_SLOT( enableAgendaUpdate( bool ) ) );
+ connect( agenda, TQT_SIGNAL(newEventSignal(ResourceCalendar *,const TQString &)),
+ TQT_SIGNAL(newEventSignal(ResourceCalendar *,const TQString &)) );
+
+ connect( agenda, TQT_SIGNAL(newStartSelectSignal()),
+ otherAgenda, TQT_SLOT(clearSelection()) );
+ connect( agenda, TQT_SIGNAL(newStartSelectSignal()),
+ TQT_SIGNAL(timeSpanSelectionChanged()) );
+
+ connect( agenda, TQT_SIGNAL(editIncidenceSignal(Incidence *,const TQDate &)),
+ TQT_SIGNAL(editIncidenceSignal(Incidence *,const TQDate &)) );
+ connect( agenda, TQT_SIGNAL(showIncidenceSignal(Incidence *,const TQDate &)),
+ TQT_SIGNAL(showIncidenceSignal(Incidence *,const TQDate &)) );
+ connect( agenda, TQT_SIGNAL(deleteIncidenceSignal(Incidence *)),
+ TQT_SIGNAL(deleteIncidenceSignal(Incidence *)) );
+
+ connect( agenda, TQT_SIGNAL(startMultiModify(const TQString &)),
+ TQT_SIGNAL(startMultiModify(const TQString &)) );
+ connect( agenda, TQT_SIGNAL(endMultiModify()),
+ TQT_SIGNAL(endMultiModify()) );
+
+ connect( agenda, TQT_SIGNAL(itemModified(KOAgendaItem *)),
+ TQT_SLOT(updateEventDates(KOAgendaItem *)) );
+
+ connect( agenda, TQT_SIGNAL(enableAgendaUpdate(bool)),
+ TQT_SLOT(enableAgendaUpdate(bool)) );
// drag signals
- connect( agenda, TQT_SIGNAL( startDragSignal( Incidence * ) ),
- TQT_SLOT( startDrag( Incidence * ) ) );
+ connect( agenda, TQT_SIGNAL(startDragSignal(Incidence *)),
+ TQT_SLOT(startDrag(Incidence *)) );
// synchronize selections
- connect( agenda, TQT_SIGNAL( incidenceSelected( Incidence * ) ),
- otherAgenda, TQT_SLOT( deselectItem() ) );
- connect( agenda, TQT_SIGNAL( incidenceSelected( Incidence * ) ),
- TQT_SIGNAL( incidenceSelected( Incidence * ) ) );
+ connect( agenda, TQT_SIGNAL(incidenceSelected(Incidence *,const TQDate &)),
+ otherAgenda, TQT_SLOT(deselectItem()) );
+ connect( agenda, TQT_SIGNAL(incidenceSelected(Incidence *,const TQDate &)),
+ TQT_SIGNAL(incidenceSelected(Incidence *,const TQDate &)) );
// rescheduling of todos by d'n'd
- connect( agenda, TQT_SIGNAL( droppedToDo( Todo *, const TQPoint &, bool ) ),
- TQT_SLOT( slotTodoDropped( Todo *, const TQPoint &, bool ) ) );
+ connect( agenda, TQT_SIGNAL(droppedToDo(Todo *,const TQPoint &,bool)),
+ TQT_SLOT(slotTodoDropped(Todo *,const TQPoint &,bool)) );
}
@@ -567,14 +596,19 @@ void KOAgendaView::zoomView( const int delta, const TQPoint &pos,
}
}
-void KOAgendaView::createDayLabels()
+void KOAgendaView::createDayLabels( bool force )
{
// kdDebug(5850) << "KOAgendaView::createDayLabels()" << endl;
- // ### 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)
+ // Check if mSelectedDates has changed, if not just return
+ // Removes some flickering and gains speed (since this is called by each updateView())
+ if ( !force && mSaveSelectedDates == mSelectedDates ) {
+ return;
+ }
+ mSaveSelectedDates = mSelectedDates;
+
delete mDayLabels;
+ mDateDayLabels.clear();
mDayLabels = new TQFrame (mDayLabelsFrame);
mLayoutDayLabels = new TQHBoxLayout(mDayLabels);
@@ -598,7 +632,8 @@ void KOAgendaView::createDayLabels()
TQString shortstr = TQString::number(calsys->day(date));
KOAlternateLabel *dayLabel = new KOAlternateLabel(shortstr,
- longstr, veryLongStr, mDayLabels);
+ longstr, veryLongStr, mDayLabels);
+ dayLabel->useShortText(); // will be recalculated in updateDayLabelSizes() anyway
dayLabel->setMinimumWidth(1);
dayLabel->setAlignment(TQLabel::AlignHCenter);
if (date == TQDate::currentDate()) {
@@ -607,6 +642,7 @@ void KOAgendaView::createDayLabels()
dayLabel->setFont(font);
}
dayLayout->addWidget(dayLabel);
+ mDateDayLabels.append( dayLabel );
// if a holiday region is selected, show the holiday name
TQStringList texts = KOGlobals::self()->holiday( date );
@@ -646,6 +682,7 @@ void KOAgendaView::createDayLabels()
if ( !mIsSideBySide )
mLayoutDayLabels->addSpacing(mAgenda->verticalScrollBar()->width());
mDayLabels->show();
+ TQTimer::singleShot( 0, this, TQT_SLOT( updateDayLabelSizes() ) );
}
void KOAgendaView::enableAgendaUpdate( bool enable )
@@ -678,7 +715,7 @@ Incidence::List KOAgendaView::selectedIncidences()
return selected;
}
-DateList KOAgendaView::selectedDates()
+DateList KOAgendaView::selectedIncidenceDates()
{
DateList selected;
TQDate qd;
@@ -766,7 +803,7 @@ void KOAgendaView::updateConfig()
setHolidayMasks();
- createDayLabels();
+ createDayLabels( true );
updateView();
}
@@ -782,12 +819,41 @@ void KOAgendaView::updateTimeBarWidth()
mTimeLabels->setFixedWidth( width );
}
+void KOAgendaView::updateDayLabelSizes()
+{
+ // First, calculate the maximum text type that fits for all labels
+ KOAlternateLabel::TextType overallType = KOAlternateLabel::Extensive;
+ TQPtrList<KOAlternateLabel>::const_iterator it = mDateDayLabels.constBegin();
+ for( ; it != mDateDayLabels.constEnd(); it++ ) {
+ KOAlternateLabel::TextType type = (*it)->largestFittingTextType();
+ if ( type < overallType )
+ overallType = type;
+ }
+
+ // Then, set that maximum text type to all the labels
+ it = mDateDayLabels.constBegin();
+ for( ; it != mDateDayLabels.constEnd(); it++ ) {
+ (*it)->setFixedType( overallType );
+ }
+}
+
+void KOAgendaView::resizeEvent( TQResizeEvent *resizeEvent )
+{
+ updateDayLabelSizes();
+ KOrg::AgendaView::resizeEvent( resizeEvent );
+}
void KOAgendaView::updateEventDates( KOAgendaItem *item )
{
- kdDebug(5850) << "KOAgendaView::updateEventDates(): " << item->text() << endl;
+ kdDebug(5850) << "KOAgendaView::updateEventDates(): " << item->text()
+ << "; item->cellXLeft(): " << item->cellXLeft()
+ << "; item->cellYTop(): " << item->cellYTop()
+ << "; item->lastMultiItem(): " << item->lastMultiItem()
+ << "; item->itemPos(): " << item->itemPos()
+ << "; item->itemCount(): " << item->itemCount()
+ << endl;
- TQDateTime startDt,endDt;
+ TQDateTime startDt, endDt;
// Start date of this incidence, calculate the offset from it (so recurring and
// non-recurring items can be treated exactly the same, we never need to check
@@ -800,17 +866,22 @@ void KOAgendaView::updateEventDates( KOAgendaItem *item )
thisDate = mSelectedDates[ item->cellXLeft() ];
}
TQDate oldThisDate( item->itemDate() );
- int daysOffset = oldThisDate.daysTo( thisDate );
+ const int daysOffset = oldThisDate.daysTo( thisDate );
int daysLength = 0;
-// startDt.setDate( startDate );
+ // startDt.setDate( startDate );
Incidence *incidence = item->incidence();
- if ( !incidence ) return;
- if ( !mChanger || !mChanger->beginChange(incidence) ) return;
+ if ( !incidence ) {
+ return;
+ }
+ if ( !mChanger ||
+ !mChanger->beginChange( incidence, resourceCalendar(), subResourceCalendar() ) ) {
+ return;
+ }
Incidence *oldIncidence = incidence->clone();
- TQTime startTime(0,0,0), endTime(0,0,0);
+ TQTime startTime( 0, 0, 0 ), endTime( 0, 0, 0 );
if ( incidence->doesFloat() ) {
daysLength = item->cellWidth() - 1;
} else {
@@ -818,12 +889,35 @@ void KOAgendaView::updateEventDates( KOAgendaItem *item )
if ( item->lastMultiItem() ) {
endTime = mAgenda->gyToTime( item->lastMultiItem()->cellYBottom() + 1 );
daysLength = item->lastMultiItem()->cellXLeft() - item->cellXLeft();
+ kdDebug(5850) << "item->lastMultiItem()->cellXLeft(): " << item->lastMultiItem()->cellXLeft()
+ << endl;
+ } else if ( item->itemPos() == item->itemCount() && item->itemCount() > 1 ) {
+ /* multiitem handling in agenda assumes two things:
+ - The start (first KOAgendaItem) is always visible.
+ - The first KOAgendaItem of the incidence has a non-null item->lastMultiItem()
+ pointing to the last KOagendaItem.
+
+ But those aren't always met, for example when in day-view.
+ kolab/issue4417
+ */
+
+ // Cornercase 1: - Resizing the end of the event but the start isn't visible
+ endTime = mAgenda->gyToTime( item->cellYBottom() + 1 );
+ daysLength = item->itemCount() - 1;
+ startTime = incidence->dtStart().time();
+ } else if ( item->itemPos() == 1 && item->itemCount() > 1 ) {
+ // Cornercase 2: - Resizing the start of the event but the end isn't visible
+ endTime = incidence->dtEnd().time();
+ daysLength = item->itemCount() - 1;
} else {
endTime = mAgenda->gyToTime( item->cellYBottom() + 1 );
}
}
-// kdDebug(5850) << "KOAgendaView::updateEventDates(): now setting dates" << endl;
+ kdDebug(5850) << "daysLength: " << daysLength << "; startTime: " << startTime
+ << "; endTime: " << endTime << "; thisDate: " << thisDate
+ << "; incidence->dtStart(): " << incidence->dtStart() << endl;
+
// FIXME: use a visitor here
if ( incidence->type() == "Event" ) {
startDt = incidence->dtStart();
@@ -831,8 +925,8 @@ void KOAgendaView::updateEventDates( KOAgendaItem *item )
startDt.setTime( startTime );
endDt = startDt.addDays( daysLength );
endDt.setTime( endTime );
- Event*ev = static_cast<Event*>(incidence);
- if( incidence->dtStart() == startDt && ev->dtEnd() == endDt ) {
+ Event* ev = static_cast<Event*>( incidence );
+ if ( incidence->dtStart() == startDt && ev->dtEnd() == endDt ) {
// No change
delete oldIncidence;
return;
@@ -840,7 +934,7 @@ void KOAgendaView::updateEventDates( KOAgendaItem *item )
incidence->setDtStart( startDt );
ev->setDtEnd( endDt );
} else if ( incidence->type() == "Todo" ) {
- Todo *td = static_cast<Todo*>(incidence);
+ Todo *td = static_cast<Todo*>( incidence );
startDt = td->hasStartDate() ? td->dtStart() : td->dtDue();
startDt = thisDate.addDays( td->dtDue().daysTo( startDt ) );
startDt.setTime( startTime );
@@ -857,8 +951,9 @@ void KOAgendaView::updateEventDates( KOAgendaItem *item )
// functionality will also be available in other views!
// TODO_Recurrence: This does not belong here, and I'm not really sure
// how it's supposed to work anyway.
- Recurrence *recur = incidence->recurrence();
-/* if ( recur->doesRecur() && daysOffset != 0 ) {
+/*
+ Recurrence *recur = incidence->recurrence();
+ if ( recur->doesRecur() && daysOffset != 0 ) {
switch ( recur->recurrenceType() ) {
case Recurrence::rYearlyPos: {
int freq = recur->frequency();
@@ -1001,23 +1096,31 @@ void KOAgendaView::updateEventDates( KOAgendaItem *item )
// FIXME: use a visitor here
if ( incidence->type() == "Event" ) {
incidence->setDtStart( startDt );
- (static_cast<Event*>( incidence ) )->setDtEnd( endDt );
+ static_cast<Event*>( incidence )->setDtEnd( endDt );
} else if ( incidence->type() == "Todo" ) {
Todo *td = static_cast<Todo*>( incidence );
- if ( td->hasStartDate() )
+ if ( td->hasStartDate() ) {
td->setDtStart( startDt );
+ }
td->setDtDue( endDt );
}
item->setItemDate( startDt.date() );
KOIncidenceToolTip::remove( item );
- KOIncidenceToolTip::add( item, incidence, KOAgendaItem::toolTipGroup() );
+ KOIncidenceToolTip::add( item, calendar(), incidence, thisDate, KOAgendaItem::toolTipGroup() );
- mChanger->changeIncidence( oldIncidence, incidence );
- mChanger->endChange(incidence);
+ const bool result = mChanger->changeIncidence( oldIncidence, incidence,
+ KOGlobals::DATE_MODIFIED, this );
+ mChanger->endChange( incidence, resourceCalendar(), subResourceCalendar() );
delete oldIncidence;
+ if ( !result ) {
+ mPendingChanges = true;
+ TQTimer::singleShot( 0, this, TQT_SLOT(updateView()) );
+ return;
+ }
+
// don't update the agenda as the item already has the correct coordinates.
// an update would delete the current item and recreate it, but we are still
// using a pointer to that item! => CRASH
@@ -1056,99 +1159,141 @@ void KOAgendaView::showDates( const TQDate &start, const TQDate &end )
mSelectedDates.clear();
TQDate d = start;
- while (d <= end) {
- mSelectedDates.append(d);
+ while ( d <= end ) {
+ mSelectedDates.append( d );
d = d.addDays( 1 );
}
+ mAreDatesInitialized = true;
+
// and update the view
fillAgenda();
}
-void KOAgendaView::showIncidences( const Incidence::List & )
+void KOAgendaView::showIncidences( const Incidence::List &, const TQDate & )
{
kdDebug(5850) << "KOAgendaView::showIncidences( const Incidence::List & ) is not yet implemented" << endl;
}
-void KOAgendaView::insertIncidence( Incidence *incidence, const TQDate &curDate,
- int curCol )
+void KOAgendaView::insertIncidence( Incidence *incidence, const TQDate &curDate )
{
- if ( !filterByResource( incidence ) )
+ if ( !filterByResource( incidence ) ) {
return;
+ }
// FIXME: Use a visitor here, or some other method to get rid of the dynamic_cast's
Event *event = dynamic_cast<Event *>( incidence );
Todo *todo = dynamic_cast<Todo *>( incidence );
+ int curCol = mSelectedDates.first().daysTo( curDate );
+
+ // In case incidence->dtStart() isn't visible (crosses bounderies)
if ( curCol < 0 ) {
- curCol = mSelectedDates.findIndex( curDate );
+ curCol = 0;
}
+
// The date for the event is not displayed, just ignore it
- if ( curCol < 0 || curCol > int( mSelectedDates.size() ) )
+ if ( curCol >= int( mSelectedDates.count() ) ) {
return;
+ }
+
+ // Default values, which can never be reached
+ mMinY[curCol] = mAgenda->timeToY( TQTime( 23, 59 ) ) + 1;
+ mMaxY[curCol] = mAgenda->timeToY( TQTime( 0, 0 ) ) - 1;
int beginX;
int endX;
+ TQDate columnDate;
if ( event ) {
- beginX = curDate.daysTo( incidence->dtStart().date() ) + curCol;
- endX = curDate.daysTo( event->dateEnd() ) + curCol;
+ TQDate firstVisibleDate = mSelectedDates.first();
+ // its crossing bounderies, lets calculate beginX and endX
+ if ( curDate < firstVisibleDate ) {
+ beginX = curCol + firstVisibleDate.daysTo( curDate );
+ endX = beginX + event->dtStart().daysTo( event->dtEnd() );
+ columnDate = firstVisibleDate;
+ } else {
+ beginX = curCol;
+ endX = beginX + event->dtStart().daysTo( event->dtEnd() );
+ columnDate = curDate;
+ }
} else if ( todo ) {
- if ( ! todo->hasDueDate() ) return; // todo shall not be displayed if it has no date
- beginX = curDate.daysTo( todo->dtDue().date() ) + curCol;
- endX = beginX;
+ if ( !todo->hasDueDate() ) {
+ return; // todo shall not be displayed if it has no date
+ }
+ columnDate = curDate;
+ beginX = endX = curCol;
+
} else {
return;
}
-
if ( todo && todo->isOverdue() ) {
- mAllDayAgenda->insertAllDayItem( incidence, curDate, curCol, curCol );
- } else if ( incidence->doesFloat() ) {
-// FIXME: This breaks with recurring multi-day events!
- if ( incidence->recurrence()->doesRecur() ) {
- mAllDayAgenda->insertAllDayItem( incidence, curDate, curCol, curCol );
- } else {
- // Insert multi-day events only on the first day, otherwise it will
- // appear multiple times
- if ( ( beginX <= 0 && curCol == 0 ) || beginX == curCol ) {
- mAllDayAgenda->insertAllDayItem( incidence, curDate, beginX, endX );
- }
- }
+ mAllDayAgenda->insertAllDayItem( incidence, columnDate, curCol, curCol );
+ } else if ( incidence->doesFloat() ||
+ ( todo &&
+ !todo->dtDue().isValid() ) ) {
+ mAllDayAgenda->insertAllDayItem( incidence, columnDate, beginX, endX );
} else if ( event && event->isMultiDay() ) {
int startY = mAgenda->timeToY( event->dtStart().time() );
- TQTime endtime( event->dtEnd().time() );
- if ( endtime == TQTime( 0, 0, 0 ) ) endtime = TQTime( 23, 59, 59 );
+ TQTime endtime = event->dtEnd().time();
+ if ( endtime == TQTime( 0, 0, 0 ) ) {
+ endtime = TQTime( 23, 59, 59 );
+ }
int endY = mAgenda->timeToY( endtime ) - 1;
- if ( (beginX <= 0 && curCol == 0) || beginX == curCol ) {
- mAgenda->insertMultiItem( event, curDate, beginX, endX, startY, endY );
+ if ( ( beginX <= 0 && curCol == 0 ) || beginX == curCol ) {
+ mAgenda->insertMultiItem( event, columnDate, beginX, endX, startY, endY );
+
}
if ( beginX == curCol ) {
- mMaxY[curCol] = mAgenda->timeToY( TQTime(23,59) );
- if ( startY < mMinY[curCol] ) mMinY[curCol] = startY;
+ mMaxY[curCol] = mAgenda->timeToY( TQTime( 23, 59 ) );
+ if ( startY < mMinY[curCol] ) {
+ mMinY[curCol] = startY;
+ }
} else if ( endX == curCol ) {
- mMinY[curCol] = mAgenda->timeToY( TQTime(0,0) );
- if ( endY > mMaxY[curCol] ) mMaxY[curCol] = endY;
+ mMinY[curCol] = mAgenda->timeToY( TQTime( 0, 0 ) );
+ if ( endY > mMaxY[curCol] ) {
+ mMaxY[curCol] = endY;
+ }
} else {
- mMinY[curCol] = mAgenda->timeToY( TQTime(0,0) );
- mMaxY[curCol] = mAgenda->timeToY( TQTime(23,59) );
+ mMinY[curCol] = mAgenda->timeToY( TQTime( 0, 0 ) );
+ mMaxY[curCol] = mAgenda->timeToY( TQTime( 23, 59 ) );
}
} else {
int startY = 0, endY = 0;
if ( event ) {
startY = mAgenda->timeToY( incidence->dtStart().time() );
- TQTime endtime( event->dtEnd().time() );
- if ( endtime == TQTime( 0, 0, 0 ) ) endtime = TQTime( 23, 59, 59 );
+ TQTime endtime = event->dtEnd().time();
+ if ( endtime == TQTime( 0, 0, 0 ) ) {
+ endtime = TQTime( 23, 59, 59 );
+ }
endY = mAgenda->timeToY( endtime ) - 1;
}
if ( todo ) {
TQTime t = todo->dtDue().time();
- endY = mAgenda->timeToY( t ) - 1;
- startY = mAgenda->timeToY( t.addSecs( -1800 ) );
+
+ if ( t == TQTime( 0, 0 ) ) {
+ t = TQTime( 23, 59 );
+ }
+
+ int halfHour = 1800;
+ if ( t.addSecs( -halfHour ) < t ) {
+ startY = mAgenda->timeToY( t.addSecs( -halfHour ) );
+ endY = mAgenda->timeToY( t ) - 1;
+ } else {
+ startY = 0;
+ endY = mAgenda->timeToY( t.addSecs( halfHour ) ) - 1;
+ }
+ }
+ if ( endY < startY ) {
+ endY = startY;
+ }
+ mAgenda->insertItem( incidence, columnDate, curCol, startY, endY, 1, 1 );
+ if ( startY < mMinY[curCol] ) {
+ mMinY[curCol] = startY;
+ }
+ if ( endY > mMaxY[curCol] ) {
+ mMaxY[curCol] = endY;
}
- if ( endY < startY ) endY = startY;
- mAgenda->insertItem( incidence, curDate, curCol, startY, endY );
- if ( startY < mMinY[curCol] ) mMinY[curCol] = startY;
- if ( endY > mMaxY[curCol] ) mMaxY[curCol] = endY;
}
}
@@ -1156,75 +1301,53 @@ void KOAgendaView::changeIncidenceDisplayAdded( Incidence *incidence )
{
Todo *todo = dynamic_cast<Todo *>(incidence);
CalFilter *filter = calendar()->filter();
- if ( filter && !filter->filterIncidence( incidence ) ||
- ( todo && !KOPrefs::instance()->showAllDayTodo() ) )
- return;
-
- TQDate f = mSelectedDates.first();
- TQDate l = mSelectedDates.last();
- TQDate startDt = incidence->dtStart().date();
-
- if ( incidence->doesRecur() ) {
- DateList::ConstIterator dit;
- TQDate curDate;
- for( dit = mSelectedDates.begin(); dit != mSelectedDates.end(); ++dit ) {
- curDate = *dit;
-// FIXME: This breaks with recurring multi-day events!
- if ( incidence->recursOn( curDate, calendar() ) ) {
- insertIncidence( incidence, curDate );
- }
- }
+ if ( ( filter && !filter->filterIncidence( incidence ) ) ||
+ ( ( todo && !KOPrefs::instance()->showAllDayTodo() ) ) ) {
return;
}
- TQDate endDt;
- if ( incidence->type() == "Event" )
- endDt = (static_cast<Event *>(incidence))->dateEnd();
- if ( todo ) {
- endDt = todo->isOverdue() ? TQDate::currentDate()
- : todo->dtDue().date();
-
- if ( endDt >= f && endDt <= l ) {
- insertIncidence( incidence, endDt );
- return;
- }
- }
-
- if ( startDt >= f && startDt <= l ) {
- insertIncidence( incidence, startDt );
- }
+ displayIncidence( incidence );
}
void KOAgendaView::changeIncidenceDisplay( Incidence *incidence, int mode )
{
switch ( mode ) {
- case KOGlobals::INCIDENCEADDED: {
- // Add an event. No need to recreate the whole view!
- // recreating everything even causes troubles: dropping to the day matrix
- // recreates the agenda items, but the evaluation is still in an agendaItems' code,
- // which was deleted in the mean time. Thus KOrg crashes...
- if ( mAllowAgendaUpdate )
- changeIncidenceDisplayAdded( incidence );
+ case KOGlobals::INCIDENCEADDED:
+ {
+ // Add an event. No need to recreate the whole view!
+ // recreating everything even causes troubles: dropping to the
+ // day matrix recreates the agenda items, but the evaluation is
+ // still in an agendaItems' code, which was deleted in the mean time.
+ // Thus KOrg crashes...
+ changeIncidenceDisplayAdded( incidence );
+ updateEventIndicators();
break;
}
- case KOGlobals::INCIDENCEEDITED: {
- if ( !mAllowAgendaUpdate ) {
- updateEventIndicators();
- } else {
+ case KOGlobals::INCIDENCEEDITED:
+ {
+ if ( mAllowAgendaUpdate ) {
removeIncidence( incidence );
- updateEventIndicators();
changeIncidenceDisplayAdded( incidence );
}
+ updateEventIndicators();
break;
}
- case KOGlobals::INCIDENCEDELETED: {
- mAgenda->removeIncidence( incidence );
- mAllDayAgenda->removeIncidence( incidence );
+ case KOGlobals::INCIDENCEDELETED:
+ {
+ removeIncidence( incidence );
updateEventIndicators();
break;
}
default:
- updateView();
+ return;
+ }
+
+ // HACK: Update the view if the all-day agenda has been modified.
+ // Do this because there are some layout problems in the
+ // all-day agenda that are not easily solved, but clearing
+ // and redrawing works ok.
+ if ( incidence->doesFloat() ) {
+ updateView();
}
}
@@ -1235,6 +1358,10 @@ void KOAgendaView::fillAgenda( const TQDate & )
void KOAgendaView::fillAgenda()
{
+ if ( !mAreDatesInitialized ) {
+ return;
+ }
+
mPendingChanges = false;
/* Remember the uids of the selected items. In case one of the
@@ -1245,115 +1372,146 @@ void KOAgendaView::fillAgenda()
enableAgendaUpdate( true );
clearView();
- mAllDayAgenda->changeColumns(mSelectedDates.count());
- mAgenda->changeColumns(mSelectedDates.count());
- mEventIndicatorTop->changeColumns(mSelectedDates.count());
- mEventIndicatorBottom->changeColumns(mSelectedDates.count());
+ mAllDayAgenda->changeColumns( mSelectedDates.count() );
+ mAgenda->changeColumns( mSelectedDates.count() );
+ mEventIndicatorTop->changeColumns( mSelectedDates.count() );
+ mEventIndicatorBottom->changeColumns( mSelectedDates.count() );
- createDayLabels();
+ createDayLabels( false );
setHolidayMasks();
- mMinY.resize(mSelectedDates.count());
- mMaxY.resize(mSelectedDates.count());
+ mMinY.resize( mSelectedDates.count() );
+ mMaxY.resize( mSelectedDates.count() );
- Event::List dayEvents;
+ mAgenda->setDateList( mSelectedDates );
- // ToDo items shall be displayed for the day they are due, but only shown today if they are already overdue.
- // Therefore, get all of them.
- Todo::List todos = calendar()->todos();
-
- mAgenda->setDateList(mSelectedDates);
+ bool somethingReselected = false;
+ Incidence::List incidences = calendar()->incidences();
- TQDate today = TQDate::currentDate();
+ for ( Incidence::List::ConstIterator it = incidences.begin(); it!=incidences.constEnd(); ++it ) {
+ Incidence *incidence = (*it);
+ displayIncidence( incidence );
- bool somethingReselected = false;
- DateList::ConstIterator dit;
- int curCol = 0;
- for( dit = mSelectedDates.begin(); dit != mSelectedDates.end(); ++dit ) {
- TQDate currentDate = *dit;
-// kdDebug(5850) << "KOAgendaView::fillAgenda(): " << currentDate.toString()
-// << endl;
-
- dayEvents = calendar()->events(currentDate,
- EventSortStartDate,
- SortDirectionAscending);
-
- // Default values, which can never be reached
- mMinY[curCol] = mAgenda->timeToY(TQTime(23,59)) + 1;
- mMaxY[curCol] = mAgenda->timeToY(TQTime(0,0)) - 1;
-
- unsigned int numEvent;
- for(numEvent=0;numEvent<dayEvents.count();++numEvent) {
- Event *event = *dayEvents.at(numEvent);
-// kdDebug(5850) << " Event: " << event->summary() << endl;
- insertIncidence( event, currentDate, curCol );
- if( event->uid() == selectedAgendaUid && !selectedAgendaUid.isNull() ) {
- mAgenda->selectItemByUID( event->uid() );
- somethingReselected = true;
- }
- if( event->uid() == selectedAllDayAgendaUid && !selectedAllDayAgendaUid.isNull() ) {
- mAllDayAgenda->selectItemByUID( event->uid() );
- somethingReselected = true;
- }
+ if( incidence->uid() == selectedAgendaUid && !selectedAgendaUid.isNull() ) {
+ mAgenda->selectItemByUID( incidence->uid() );
+ somethingReselected = true;
+ }
+ if( incidence->uid() == selectedAllDayAgendaUid && !selectedAllDayAgendaUid.isNull() ) {
+ mAllDayAgenda->selectItemByUID( incidence->uid() );
+ somethingReselected = true;
}
-// if (numEvent == 0) kdDebug(5850) << " No events" << endl;
+ }
+
+ mAgenda->checkScrollBoundaries();
+ updateEventIndicators();
+
+ // mAgenda->viewport()->update();
+ // mAllDayAgenda->viewport()->update();
- // ---------- [display Todos --------------
- if ( KOPrefs::instance()->showAllDayTodo() ) {
- unsigned int numTodo;
- for (numTodo = 0; numTodo < todos.count(); ++numTodo) {
- Todo *todo = *todos.at(numTodo);
+ // make invalid
+ deleteSelectedDateTime();
- if ( ! todo->hasDueDate() ) continue; // todo shall not be displayed if it has no date
+ if( !somethingReselected ) {
+ emit incidenceSelected( 0, TQDate() );
+ }
+}
- if ( !filterByResource( todo ) ) continue;
+void KOAgendaView::displayIncidence( Incidence *incidence )
+{
+ TQDate today = TQDate::currentDate();
+ DateTimeList::iterator t;
- // 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
- bool overdue = todo->isOverdue();
+ // FIXME: use a visitor here
+ Todo *todo = dynamic_cast<Todo *>( incidence );
+ Event *event = dynamic_cast<Event *>( incidence );
- if ( (( todo->dtDue().date() == currentDate) && !overdue) ||
- (( currentDate == today) && overdue) ||
- ( todo->recursOn( currentDate ) ) ) {
- if ( todo->doesFloat() || overdue ) { // Todo has no due-time set or is already overdue
- //kdDebug(5850) << "todo without time:" << todo->dtDueDateStr() << ";" << todo->summary() << endl;
+ TQDateTime firstVisibleDateTime = mSelectedDates.first();
+ TQDateTime lastVisibleDateTime = mSelectedDates.last();
- mAllDayAgenda->insertAllDayItem(todo, currentDate, curCol, curCol);
- } else {
- //kdDebug(5850) << "todo with time:" << todo->dtDueStr() << ";" << todo->summary() << endl;
+ lastVisibleDateTime.setTime( TQTime( 23, 59, 59, 59 ) );
+ firstVisibleDateTime.setTime( TQTime( 0, 0 ) );
+ DateTimeList dateTimeList;
- int endY = mAgenda->timeToY(todo->dtDue().time()) - 1;
- int startY = endY - 1;
+ TQDateTime incDtStart = incidence->dtStart();
+ TQDateTime incDtEnd = incidence->dtEnd();
- mAgenda->insertItem(todo,currentDate,curCol,startY,endY);
+ if ( todo &&
+ ( !KOPrefs::instance()->showAllDayTodo() || !todo->hasDueDate() ) ) {
+ return;
+ }
- if (startY < mMinY[curCol]) mMinY[curCol] = startY;
- if (endY > mMaxY[curCol]) mMaxY[curCol] = endY;
- }
- }
+ if ( incidence->doesRecur() ) {
+ int eventDuration = event ? incDtStart.daysTo( incDtEnd ) : 0;
+
+ // if there's a multiday event that starts before firstVisibleDateTime but ends after
+ // lets include it. timesInInterval() ignores incidences that aren't totaly inside
+ // the range
+ TQDateTime startDateTimeWithOffset = firstVisibleDateTime.addDays( -eventDuration );
+ dateTimeList =
+ incidence->recurrence()->timesInInterval( startDateTimeWithOffset,
+ lastVisibleDateTime );
+ } else {
+ TQDateTime dateToAdd; // date to add to our date list
+ TQDateTime incidenceStart;
+ TQDateTime incidenceEnd;
+
+ if ( todo && todo->hasDueDate() && !todo->isOverdue() ) {
+ // If it's not overdue it will be shown at the original date (not today)
+ dateToAdd = todo->dtDue();
+
+ // To-dos are drawn with the bottom of the rectangle at dtDue
+ // if dtDue is at 00:00, then it should be displayed in the previous day, at 23:59
+ if ( !todo->doesFloat() && dateToAdd.time() == TQTime( 0, 0 ) ) {
+ dateToAdd = dateToAdd.addSecs( -1 );
}
- }
- // ---------- display Todos] --------------
- ++curCol;
- }
+ incidenceEnd = dateToAdd;
+ } else if ( event ) {
+ dateToAdd = incDtStart;
+ incidenceEnd = incDtEnd;
+ }
- mAgenda->checkScrollBoundaries();
- updateEventIndicators();
+ if ( incidence->doesFloat() ) {
+ // so comparisons with < > actually work
+ dateToAdd.setTime( TQTime( 0, 0 ) );
+ incidenceEnd.setTime( TQTime( 23, 59, 59, 59 ) );
+ }
-// mAgenda->viewport()->update();
-// mAllDayAgenda->viewport()->update();
+ if ( dateToAdd <= lastVisibleDateTime && incidenceEnd > firstVisibleDateTime ) {
+ dateTimeList += dateToAdd;
+ }
+ }
-// make invalid
- deleteSelectedDateTime();
+ // ToDo items shall be displayed today if they are already overdude
+ TQDateTime dateTimeToday = today;
+ if ( todo &&
+ todo->isOverdue() &&
+ dateTimeToday >= firstVisibleDateTime &&
+ dateTimeToday <= lastVisibleDateTime ) {
+
+ bool doAdd = true;
+
+ if ( todo->doesRecur() ) {
+ /* If there's a recurring instance showing up today don't add "today" again
+ * we don't want the event to appear duplicated */
+ for ( t = dateTimeList.begin(); t != dateTimeList.end(); ++t ) {
+ if ( (*t).date() == today ) {
+ doAdd = false;
+ break;
+ }
+ }
+ }
- if( !somethingReselected ) {
- emit incidenceSelected( 0 );
+ if ( doAdd ) {
+ dateTimeList += dateTimeToday;
+ }
}
-// kdDebug(5850) << "Fill Agenda done" << endl;
+ for ( t = dateTimeList.begin(); t != dateTimeList.end(); ++t ) {
+ insertIncidence( incidence, (*t).date() );
+ }
}
void KOAgendaView::clearView()
@@ -1373,7 +1531,7 @@ void KOAgendaView::updateEventIndicatorTop( int newY )
{
uint i;
for( i = 0; i < mMinY.size(); ++i ) {
- mEventIndicatorTop->enableColumn( i, newY >= mMinY[i] );
+ mEventIndicatorTop->enableColumn( i, newY > mMinY[i] );
}
mEventIndicatorTop->update();
}
@@ -1399,12 +1557,14 @@ void KOAgendaView::slotTodoDropped( Todo *todo, const TQPoint &gpos, bool allDay
if ( existingTodo ) {
kdDebug(5850) << "Drop existing Todo" << endl;
Todo *oldTodo = existingTodo->clone();
- if ( mChanger && mChanger->beginChange( existingTodo ) ) {
+ if ( mChanger &&
+ mChanger->beginChange( existingTodo, resourceCalendar(), subResourceCalendar() ) ) {
existingTodo->setDtDue( newTime );
existingTodo->setFloats( allDay );
existingTodo->setHasDueDate( true );
- mChanger->changeIncidence( oldTodo, existingTodo );
- mChanger->endChange( existingTodo );
+ mChanger->changeIncidence( oldTodo, existingTodo,
+ KOGlobals::DATE_MODIFIED, this );
+ mChanger->endChange( existingTodo, resourceCalendar(), subResourceCalendar() );
} else {
KMessageBox::sorry( this, i18n("Unable to modify this to-do, "
"because it cannot be locked.") );
@@ -1415,7 +1575,7 @@ void KOAgendaView::slotTodoDropped( Todo *todo, const TQPoint &gpos, bool allDay
todo->setDtDue( newTime );
todo->setFloats( allDay );
todo->setHasDueDate( true );
- if ( !mChanger->addIncidence( todo, this ) ) {
+ if ( !mChanger->addIncidence( todo, 0, TQString(), this ) ) {
KODialogManager::errorSaveIncidence( this, todo );
}
}
@@ -1468,6 +1628,10 @@ void KOAgendaView::writeSettings(KConfig *config)
void KOAgendaView::setHolidayMasks()
{
+ if ( mSelectedDates.isEmpty() || !mSelectedDates[0].isValid() ) {
+ return;
+ }
+
mHolidayMask.resize( mSelectedDates.count() + 1 );
for( uint i = 0; i < mSelectedDates.count(); ++i ) {
@@ -1579,23 +1743,34 @@ void KOAgendaView::clearTimeSpanSelection()
deleteSelectedDateTime();
}
-void KOAgendaView::setResource(KCal::ResourceCalendar * res, const TQString & subResource)
-{
- mResource = res;
- mSubResource = subResource;
-}
+bool KOAgendaView::filterByResource( Incidence *incidence )
+{
+ // Special handling for groupware to-dos that are in Task folders.
+ // Put them in the top-level "Calendar" folder for lack of a better
+ // place since we never show Task type folders even in the
+ // multiagenda view.
+ if ( resourceCalendar() && incidence->type() == "Todo" ) {
+ TQString subRes = resourceCalendar()->subresourceIdentifier( incidence );
+ if ( resourceCalendar()->subresourceType( subRes ) == "todo" ) {
+ TQString calmatch = "/.INBOX.directory/Calendar";
+ TQString i18nmatch = "/.INBOX.directory/" + i18n( "Calendar" );
+ if ( subResourceCalendar().contains( calmatch ) ||
+ subResourceCalendar().contains( i18nmatch ) ) {
+ return true;
+ }
+ }
+ }
-bool KOAgendaView::filterByResource(Incidence * incidence)
-{
- if ( !mResource )
+ // Normal handling
+ if ( !resourceCalendar() )
return true;
CalendarResources *calRes = dynamic_cast<CalendarResources*>( calendar() );
if ( !calRes )
return true;
- if ( calRes->resource( incidence ) != mResource )
+ if ( calRes->resource( incidence ) != resourceCalendar() )
return false;
- if ( !mSubResource.isEmpty() ) {
- if ( mResource->subresourceIdentifier( incidence ) != mSubResource )
+ if ( !subResourceCalendar().isEmpty() ) {
+ if ( resourceCalendar()->subresourceIdentifier( incidence ) != subResourceCalendar() )
return false;
}
return true;
@@ -1618,7 +1793,7 @@ void KOAgendaView::calendarIncidenceChanged(Incidence * incidence)
mPendingChanges = true;
}
-void KOAgendaView::calendarIncidenceRemoved(Incidence * incidence)
+void KOAgendaView::calendarIncidenceDeleted(Incidence * incidence)
{
Q_UNUSED( incidence );
mPendingChanges = true;
diff --git a/korganizer/koagendaview.h b/korganizer/koagendaview.h
index 1a16b2bb..a31581a0 100644
--- a/korganizer/koagendaview.h
+++ b/korganizer/koagendaview.h
@@ -31,6 +31,7 @@
#include <libkcal/calendar.h>
#include "calprinter.h"
+#include "calendarview.h"
#include "agendaview.h"
@@ -43,10 +44,6 @@ class KOAgendaItem;
class TimeLabels;
class KConfig;
-namespace KCal {
- class ResourceCalendar;
-}
-
namespace KOrg {
class IncidenceChangerBase;
}
@@ -85,8 +82,11 @@ class KOAlternateLabel : public QLabel
virtual TQSize minimumSizeHint() const;
+ enum TextType { Short = 0, Long = 1, Extensive = 2 };
+ TextType largestFittingTextType() const;
+ void setFixedType( TextType type );
+
public slots:
- void setText( const TQString & );
void useShortText();
void useLongText();
void useExtensiveText();
@@ -107,11 +107,13 @@ class KOAgendaView : public KOrg::AgendaView, public KCal::Calendar::Observer
{
Q_OBJECT
public:
- KOAgendaView( Calendar *cal, TQWidget *parent = 0, const char *name = 0, bool isSideBySide = false );
+ KOAgendaView( Calendar *cal,
+ CalendarView *calendarView,
+ TQWidget *parent = 0,
+ const char *name = 0,
+ bool isSideBySide = false );
virtual ~KOAgendaView();
-
-
/** Returns maximum number of days supported by the koagendaview */
virtual int maxDatesHint();
@@ -122,7 +124,7 @@ class KOAgendaView : public KOrg::AgendaView, public KCal::Calendar::Observer
virtual Incidence::List selectedIncidences();
/** returns the currently selected events */
- virtual DateList selectedDates();
+ virtual DateList selectedIncidenceDates();
/** return the default start/end date/time for new events */
virtual bool eventDurationHint(TQDateTime &startDt, TQDateTime &endDt, bool &allDay);
@@ -145,24 +147,22 @@ class KOAgendaView : public KOrg::AgendaView, public KCal::Calendar::Observer
void setTypeAheadReceiver( TQObject * );
- /** Show only incidences from the given resource. */
- void setResource( KCal::ResourceCalendar *res, const TQString &subResource = TQString::null );
-
KOAgenda* agenda() const { return mAgenda; }
TQSplitter* splitter() const { return mSplitterAgenda; }
+ TQFrame *dayLabels() const { return mDayLabels; }
/* reimplmented from KCal::Calendar::Observer */
void calendarIncidenceAdded( Incidence *incidence );
void calendarIncidenceChanged( Incidence *incidence );
- void calendarIncidenceRemoved( Incidence *incidence );
+ void calendarIncidenceDeleted( Incidence *incidence );
public slots:
virtual void updateView();
virtual void updateConfig();
virtual void showDates( const TQDate &start, const TQDate &end );
- virtual void showIncidences( const Incidence::List &incidenceList );
+ virtual void showIncidences( const Incidence::List &incidenceList, const TQDate &date );
- void insertIncidence( Incidence *incidence, const TQDate &curDate, int curCol = -1 );
+ void insertIncidence( Incidence *incidence, const TQDate &curDate );
void changeIncidenceDisplayAdded( Incidence *incidence );
void changeIncidenceDisplay( Incidence *incidence, int mode );
@@ -215,7 +215,7 @@ class KOAgendaView : public KOrg::AgendaView, public KCal::Calendar::Observer
void connectAgenda( KOAgenda*agenda, TQPopupMenu*popup, KOAgenda* otherAgenda );
/** Create labels for the selected dates. */
- void createDayLabels();
+ void createDayLabels( bool force );
/**
Set the masks on the agenda widgets indicating, which days are holidays.
@@ -231,6 +231,8 @@ class KOAgendaView : public KOrg::AgendaView, public KCal::Calendar::Observer
void updateTimeBarWidth();
+ virtual void resizeEvent( TQResizeEvent *resizeEvent );
+
protected slots:
/** Update event belonging to agenda item */
void updateEventDates( KOAgendaItem *item );
@@ -245,14 +247,18 @@ class KOAgendaView : public KOrg::AgendaView, public KCal::Calendar::Observer
/** Updates data for selected timespan for all day event*/
void newTimeSpanSelectedAllDay( const TQPoint &start, const TQPoint &end );
+ void updateDayLabelSizes();
+
private:
bool filterByResource( Incidence *incidence );
+ void displayIncidence( Incidence *incidence );
private:
// view widgets
TQFrame *mDayLabels;
TQHBox *mDayLabelsFrame;
TQBoxLayout *mLayoutDayLabels;
+ TQPtrList<KOAlternateLabel> mDateDayLabels;
TQFrame *mAllDayFrame;
KOAgenda *mAllDayAgenda;
KOAgenda *mAgenda;
@@ -262,6 +268,7 @@ class KOAgendaView : public KOrg::AgendaView, public KCal::Calendar::Observer
TQPushButton *mExpandButton;
DateList mSelectedDates; // List of dates to be displayed
+ DateList mSaveSelectedDates; // Save the list of dates between updateViews
int mViewType;
KOEventPopupMenu *mAgendaPopup;
@@ -285,11 +292,16 @@ class KOAgendaView : public KOrg::AgendaView, public KCal::Calendar::Observer
Incidence *mUpdateItem;
- KCal::ResourceCalendar *mResource;
- TQString mSubResource;
-
bool mIsSideBySide;
bool mPendingChanges;
+
+ // the current date is inserted into mSelectedDates in the constructor
+ // however whe should only show events when setDates is called, otherwise
+ // we see day view with current date for a few milisecs, then we see something else
+ // because someone called setDates with the real dates that should be displayed.
+ // Other solution would be not initializing mSelectedDates in the ctor, but that requires
+ // lots of changes in koagenda.cpp and koagendaview.cpp
+ bool mAreDatesInitialized;
};
#endif
diff --git a/korganizer/koattendeeeditor.cpp b/korganizer/koattendeeeditor.cpp
index 370ac3b3..8766a333 100644
--- a/korganizer/koattendeeeditor.cpp
+++ b/korganizer/koattendeeeditor.cpp
@@ -18,6 +18,8 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+#include <config.h> // for KDEPIM_NEW_DISTRLISTS
+
#include "koattendeeeditor.h"
#include "koprefs.h"
#include "koglobals.h"
@@ -32,8 +34,16 @@
#include <libemailfunctions/email.h>
+#ifdef KDEPIM_NEW_DISTRLISTS
+#include "distributionlist.h"
+#else
+#include <kabc/distributionlist.h>
+#endif
+#include <kabc/stdaddressbook.h>
+
#include <kiconloader.h>
#include <klocale.h>
+#include <kmessagebox.h>
#include <tqcheckbox.h>
#include <tqcombobox.h>
@@ -101,6 +111,7 @@ void KOAttendeeEditor::initEditWidgets(TQWidget * parent, TQBoxLayout * layout)
mNameEdit->installEventFilter( this );
connect( mNameEdit, TQT_SIGNAL( textChanged( const TQString & ) ),
TQT_SLOT( updateAttendee() ) );
+ connect( mNameEdit, TQT_SIGNAL(returnPressed()), TQT_SLOT(expandAttendee()) );
topLayout->addMultiCellWidget( mNameEdit, 0, 0, 1, 2 );
whatsThis = i18n("Edits the role of the attendee selected "
@@ -206,20 +217,6 @@ void KOAttendeeEditor::openAddressBook()
}
delete dia;
return;
-#if 0
- // old code
- KABC::Addressee a = KABC::AddresseeDialog::getAddressee(this);
- if (!a.isEmpty()) {
- // If this is myself, I don't want to get a response but instead
- // assume I will be available
- bool myself = KOPrefs::instance()->thatIsMe( a.preferredEmail() );
- KCal::Attendee::PartStat partStat =
- myself ? KCal::Attendee::Accepted : KCal::Attendee::NeedsAction;
- insertAttendee( new Attendee( a.realName(), a.preferredEmail(),
- !myself, partStat,
- KCal::Attendee::ReqParticipant, a.uid() ) );
- }
-#endif
#endif
}
@@ -236,12 +233,13 @@ void KOAttendeeEditor::insertAttendeeFromAddressee(const KABC::Addressee &a, con
rsvp = false;
}
Attendee *newAt = new Attendee( a.realName(),
- a.preferredEmail(),
- !myself, partStat,
- at ? at->role() : Attendee::ReqParticipant,
- a.uid() );
+ a.preferredEmail(),
+ !myself, partStat,
+ at ? at->role() : Attendee::ReqParticipant,
+ a.uid() );
newAt->setRSVP( rsvp );
insertAttendee( newAt, true );
+ mnewAttendees.append( newAt );
}
void KOAttendeeEditor::fillOrganizerCombo()
@@ -260,10 +258,21 @@ void KOAttendeeEditor::fillOrganizerCombo()
void KOAttendeeEditor::addNewAttendee()
{
+ // check if there's still an unchanged example entry, and if so
+ // suggest to edit that first
+ if ( TQListViewItem* item = hasExampleAttendee() ) {
+ KMessageBox::information( this,
+ i18n( "Please edit the example attendee, before adding more." ), TQString::null,
+ "EditExistingExampleAttendeeFirst" );
+ // make sure the example attendee is selected
+ item->setSelected( true );
+ item->listView()->setCurrentItem( item );
+ return;
+ }
Attendee *a = new Attendee( i18n("Firstname Lastname"),
i18n("name") + "@example.net", true );
insertAttendee( a, false );
- mnewAttendees.append(a);
+ mnewAttendees.append( a );
updateAttendeeInput();
// We don't want the hint again
mNameEdit->setClickMessage( "" );
@@ -275,7 +284,7 @@ void KOAttendeeEditor::readEvent(KCal::Incidence * incidence)
{
mdelAttendees.clear();
mnewAttendees.clear();
- if ( KOPrefs::instance()->thatIsMe( incidence->organizer().email() ) ) {
+ if ( KOPrefs::instance()->thatIsMe( incidence->organizer().email() ) || incidence->organizer().isEmpty() ) {
if ( !mOrganizerCombo ) {
mOrganizerCombo = new TQComboBox( mOrganizerHBox );
fillOrganizerCombo();
@@ -305,8 +314,36 @@ void KOAttendeeEditor::readEvent(KCal::Incidence * incidence)
Attendee::List al = incidence->attendees();
Attendee::List::ConstIterator it;
- for( it = al.begin(); it != al.end(); ++it )
- insertAttendee( new Attendee( **it ), true );
+ Attendee *first = 0;
+ for( it = al.begin(); it != al.end(); ++it ) {
+ Attendee *a = new Attendee( **it );
+ if ( !first ) {
+ first = a;
+ }
+ insertAttendee( a, true );
+ }
+
+ // Set the initial editing values to the first attendee in the list.
+ if ( first ) {
+ // Don't update the item here, the user didn't edit it, so it's not needed.
+ // Also, AttendeeEditor's subclasses didn't set the current Item at this point
+ // so if updateAttendee is called now what will happen is that a random item
+ // will get the text of "first".
+ mDisableItemUpdate = true;
+
+ setSelected( 0 );
+ mNameEdit->setText( first->fullName() );
+ mUid = first->uid();
+ mRoleCombo->setCurrentItem( first->role() );
+ if ( first->status() != KCal::Attendee::None ) {
+ mStatusCombo->setCurrentItem( first->status() );
+ } else {
+ mStatusCombo->setCurrentItem( KCal::Attendee::NeedsAction );
+ }
+ mRsvpButton->setChecked( first->RSVP() );
+ mRsvpButton->setEnabled( true );
+ mDisableItemUpdate = false;
+ }
}
void KOAttendeeEditor::writeEvent(KCal::Incidence * incidence)
@@ -338,15 +375,39 @@ void KOAttendeeEditor::clearAttendeeInput()
mDelegateLabel->setText( TQString() );
}
+void KOAttendeeEditor::expandAttendee()
+{
+ KABC::Addressee::List aList = expandDistList( mNameEdit->text() );
+ if ( !aList.isEmpty() ) {
+ int index = selectedIndex();
+ for ( KABC::Addressee::List::iterator itr = aList.begin(); itr != aList.end(); ++itr ) {
+ insertAttendeeFromAddressee( (*itr) );
+ }
+ setSelected( index );
+ removeAttendee( currentAttendee() );
+ }
+}
+
void KOAttendeeEditor::updateAttendee()
{
Attendee *a = currentAttendee();
if ( !a || mDisableItemUpdate )
return;
- TQString name;
- TQString email;
- KPIM::getNameAndMail(mNameEdit->text(), name, email);
+ TQString text = mNameEdit->text();
+ if ( !mNameEdit->text().startsWith( "\"" ) ) {
+ // Quote the text as it might contain commas and other quotable chars.
+ text = KPIM::quoteNameIfNecessary( text );
+ }
+
+ TQString name, email;
+ if ( KPIM::getNameAndMail( text, name, email ) ) {
+ name.remove( '"' );
+ email.remove( '"' ).remove( '>' );
+ } else {
+ name = TQString();
+ email = mNameEdit->text();
+ }
bool iAmTheOrganizer = mOrganizerCombo &&
KOPrefs::instance()->thatIsMe( mOrganizerCombo->currentText() );
@@ -356,7 +417,6 @@ void KOAttendeeEditor::updateAttendee()
bool wasMyself =
KPIM::compareEmail( a->email(), mOrganizerCombo->currentText(), false );
if ( myself ) {
- mStatusCombo->setCurrentItem( KCal::Attendee::Accepted );
mRsvpButton->setChecked( false );
mRsvpButton->setEnabled( false );
} else if ( wasMyself ) {
@@ -380,16 +440,37 @@ void KOAttendeeEditor::fillAttendeeInput( KCal::Attendee *a )
{
mDisableItemUpdate = true;
- TQString name = a->name();
- if (!a->email().isEmpty()) {
- name = KPIM::quoteNameIfNecessary( name );
- name += " <" + a->email() + ">";
+ TQString tname, temail;
+ TQString username = a->name();
+ if ( !a->email().isEmpty() ) {
+ username = KPIM::quoteNameIfNecessary( username );
+
+ KPIM::getNameAndMail( username, tname, temail ); // ignore return value
+ // which is always false
+ tname += " <" + a->email() + '>';
+ }
+
+ bool myself = KOPrefs::instance()->thatIsMe( a->email() );
+ bool sameAsOrganizer = mOrganizerCombo &&
+ KPIM::compareEmail( a->email(),
+ mOrganizerCombo->currentText(), false );
+ KCal::Attendee::PartStat partStat = a->status();
+ bool rsvp = a->RSVP();
+
+ if ( myself && sameAsOrganizer && a->status() == KCal::Attendee::None ) {
+ partStat = KCal::Attendee::Accepted;
+ rsvp = false;
}
- mNameEdit->setText(name);
+
+ mNameEdit->setText(tname);
mUid = a->uid();
mRoleCombo->setCurrentItem(a->role());
- mStatusCombo->setCurrentItem(a->status());
- mRsvpButton->setChecked(a->RSVP());
+ if ( partStat != KCal::Attendee::None ) {
+ mStatusCombo->setCurrentItem( partStat );
+ } else {
+ mStatusCombo->setCurrentItem( KCal::Attendee::NeedsAction );
+ }
+ mRsvpButton->setChecked( rsvp );
mDisableItemUpdate = false;
setEnableAttendeeInput( true );
@@ -402,6 +483,9 @@ void KOAttendeeEditor::fillAttendeeInput( KCal::Attendee *a )
else
mDelegateLabel->setText( i18n( "Not delegated" ) );
}
+ if( myself )
+ mRsvpButton->setEnabled( false );
+
}
void KOAttendeeEditor::updateAttendeeInput()
@@ -418,17 +502,24 @@ void KOAttendeeEditor::updateAttendeeInput()
void KOAttendeeEditor::cancelAttendeeEvent( KCal::Incidence *incidence )
{
incidence->clearAttendees();
- Attendee * att;
- for (att=mdelAttendees.first();att;att=mdelAttendees.next()) {
+
+ if ( mdelAttendees.isEmpty() ) {
+ return;
+ }
+
+ Attendee *att;
+ for ( att = mdelAttendees.first(); att; att = mdelAttendees.next() ) {
bool isNewAttendee = false;
- for (Attendee *newAtt=mnewAttendees.first();newAtt;newAtt=mnewAttendees.next()) {
- if (*att==*newAtt) {
- isNewAttendee = true;
- break;
+ if ( !mnewAttendees.isEmpty() ) {
+ for ( Attendee *newAtt = mnewAttendees.first(); newAtt; newAtt = mnewAttendees.next() ) {
+ if ( *att == *newAtt ) {
+ isNewAttendee = true;
+ break;
+ }
}
}
- if (!isNewAttendee) {
- incidence->addAttendee(new Attendee(*att));
+ if ( !isNewAttendee ) {
+ incidence->addAttendee( new Attendee( *att ) );
}
}
mdelAttendees.clear();
@@ -454,4 +545,51 @@ bool KOAttendeeEditor::eventFilter(TQObject *watched, TQEvent *ev)
return TQWidget::eventFilter( watched, ev );
}
+bool KOAttendeeEditor::isExampleAttendee( const KCal::Attendee* attendee ) const
+{
+ if ( !attendee ) return false;
+ if ( attendee->name() == i18n( "Firstname Lastname" )
+ && attendee->email().endsWith( "example.net" ) ) {
+ return true;
+ }
+ return false;
+}
+
+KABC::Addressee::List KOAttendeeEditor::expandDistList( const TQString &text ) const
+{
+ KABC::Addressee::List aList;
+ KABC::AddressBook *abook = KABC::StdAddressBook::self( true );
+
+#ifdef KDEPIM_NEW_DISTRLISTS
+ const TQValueList<KPIM::DistributionList::Entry> eList =
+ KPIM::DistributionList::findByName( abook, text ).entries( abook );
+ TQValueList<KPIM::DistributionList::Entry>::ConstIterator eit;
+ for ( eit = eList.begin(); eit != eList.end(); ++eit ) {
+ KABC::Addressee a = (*eit).addressee;
+ if ( !a.preferredEmail().isEmpty() && aList.find( a ) == aList.end() ) {
+ aList.append( a ) ;
+ }
+ }
+
+#else
+ KABC::DistributionListManager manager( abook );
+ manager.load();
+ const TQStringList dList = manager.listNames();
+ for ( TQStringList::ConstIterator it = dList.begin(); it != dList.end(); ++it ) {
+ if ( (*it) == text ) {
+ const TQValueList<KABC::DistributionList::Entry> eList = manager.list( *it )->entries();
+ TQValueList<KABC::DistributionList::Entry>::ConstIterator eit;
+ for ( eit = eList.begin(); eit != eList.end(); ++eit ) {
+ KABC::Addressee a = (*eit).addressee;
+ if ( !a.preferredEmail().isEmpty() && aList.find( a ) == aList.end() ) {
+ aList.append( a ) ;
+ }
+ }
+ }
+ }
+#endif
+ return aList;
+}
+
+
#include "koattendeeeditor.moc"
diff --git a/korganizer/koattendeeeditor.h b/korganizer/koattendeeeditor.h
index 5f1dfb97..e75d994e 100644
--- a/korganizer/koattendeeeditor.h
+++ b/korganizer/koattendeeeditor.h
@@ -23,6 +23,7 @@
#include <tqwidget.h>
#include <libkcal/attendee.h>
+#include <kabc/addressee.h>
class TQBoxLayout;
class TQComboBox;
@@ -30,15 +31,12 @@ class TQCheckBox;
class TQLabel;
class TQPushButton;
class TQHBox;
+class TQListViewItem;
namespace KPIM {
class AddresseeLineEdit;
}
-namespace KABC {
- class Addressee;
-}
-
namespace KCal {
class Incidence;
}
@@ -52,7 +50,8 @@ class KOAttendeeEditor : public QWidget
public:
KOAttendeeEditor( TQWidget *parent, const char *name = 0 );
- virtual void insertAttendee( KCal::Attendee* attendee, bool fetchFB = true ) = 0;
+ virtual void insertAttendee( KCal::Attendee *attendee, bool fetchFB = true ) = 0;
+ virtual void removeAttendee( KCal::Attendee *attendee ) = 0;
virtual void readEvent( KCal::Incidence *incidence );
virtual void writeEvent( KCal::Incidence *incidence );
@@ -79,10 +78,13 @@ class KOAttendeeEditor : public QWidget
void insertAttendeeFromAddressee( const KABC::Addressee &a, const KCal::Attendee* at=0 );
void fillOrganizerCombo();
-
+ virtual TQListViewItem* hasExampleAttendee() const = 0;
+ bool isExampleAttendee( const KCal::Attendee* ) const;
virtual KCal::Attendee* currentAttendee() const = 0;
virtual void updateCurrentItem() = 0;
+ virtual void setSelected ( int index ) = 0;
+ virtual int selectedIndex() = 0;
virtual void changeStatusForMe( KCal::Attendee::PartStat status ) = 0;
virtual bool eventFilter( TQObject *, TQEvent *);
@@ -95,6 +97,7 @@ class KOAttendeeEditor : public QWidget
void updateAttendeeInput();
void clearAttendeeInput();
void fillAttendeeInput( KCal::Attendee *a );
+ void expandAttendee();
void updateAttendee();
protected:
@@ -118,6 +121,7 @@ class KOAttendeeEditor : public QWidget
TQPtrList<KCal::Attendee> mnewAttendees;
private:
+ KABC::Addressee::List expandDistList( const TQString &text ) const;
bool mDisableItemUpdate;
};
diff --git a/korganizer/kocorehelper.cpp b/korganizer/kocorehelper.cpp
index 374c7107..5538d9c3 100644
--- a/korganizer/kocorehelper.cpp
+++ b/korganizer/kocorehelper.cpp
@@ -26,13 +26,17 @@
#include "koglobals.h"
-TQColor KOCoreHelper::categoryColor( const TQStringList &categories )
+TQColor KOCoreHelper::categoryColor( const TQStringList &categories )
{
+ if ( categories.isEmpty() ) {
+ return KOPrefs::instance()->unsetCategoryColor();
+ }
+
// FIXME: Correctly treat events with multiple categories
TQString cat = categories.first();
TQColor bgColor;
if (cat.isEmpty())
- bgColor = defaultEventColor();
+ bgColor = KOPrefs::instance()->unsetCategoryColor();
else
bgColor = *( KOPrefs::instance()->categoryColor( cat ) );
return bgColor;
diff --git a/korganizer/kocorehelper.h b/korganizer/kocorehelper.h
index 60927856..ff3c55a3 100644
--- a/korganizer/kocorehelper.h
+++ b/korganizer/kocorehelper.h
@@ -40,7 +40,6 @@ class KOCoreHelper : public KOrg::CoreHelper
KOCoreHelper() {}
virtual ~KOCoreHelper() {}
- virtual TQColor defaultEventColor() { return KOPrefs::instance()->mEventColor; }
virtual TQColor textColor( const TQColor &bgColor ) { return getTextColor( bgColor ); }
virtual TQColor categoryColor( const TQStringList &cats );
virtual TQString holidayString( const TQDate &dt );
diff --git a/korganizer/kocounterdialog.cpp b/korganizer/kocounterdialog.cpp
index bf3f736f..a8a581d0 100644
--- a/korganizer/kocounterdialog.cpp
+++ b/korganizer/kocounterdialog.cpp
@@ -32,11 +32,11 @@
#include "kocounterdialog.h"
#include "kocounterdialog.moc"
-KOCounterDialog::KOCounterDialog( TQWidget *parent, const char *name )
+KOCounterDialog::KOCounterDialog( Calendar *calendar, TQWidget *parent, const char *name )
: KDialogBase( parent, name, false, i18n("Counter-Event Viewer"),
User1 | User2, User1, false, i18n("Decline"), i18n("Accept") )
{
- mEventViewer = new KOEventViewer( this );
+ mEventViewer = new KOEventViewer( calendar, this );
setMainWidget( mEventViewer );
connect( this, TQT_SIGNAL( user1Clicked() ), TQT_SLOT( slotCancel() ) );
diff --git a/korganizer/kocounterdialog.h b/korganizer/kocounterdialog.h
index cedb9dab..64757e98 100644
--- a/korganizer/kocounterdialog.h
+++ b/korganizer/kocounterdialog.h
@@ -27,8 +27,7 @@
#include <kdialogbase.h>
namespace KCal {
-class Event;
-class Todo;
+class Calendar;
}
using namespace KCal;
@@ -41,7 +40,7 @@ class KOCounterDialog : public KDialogBase
{
Q_OBJECT
public:
- KOCounterDialog(TQWidget *parent = 0, const char *name = 0 );
+ KOCounterDialog(Calendar *calendar, TQWidget *parent = 0, const char *name = 0 );
virtual ~KOCounterDialog();
void setIncidence( Incidence *incidence );
diff --git a/korganizer/kodaymatrix.cpp b/korganizer/kodaymatrix.cpp
index ff82ada9..065e44e7 100644
--- a/korganizer/kodaymatrix.cpp
+++ b/korganizer/kodaymatrix.cpp
@@ -228,11 +228,15 @@ void KODayMatrix::recalculateToday()
updateView( mStartDate );
}
+void KODayMatrix::setUpdateNeeded()
+{
+ mPendingChanges = true;
+}
+
void KODayMatrix::updateView( const TQDate &actdate )
{
kdDebug(5850) << "KODayMatrix::updateView() " << actdate << ", day start="<<mStartDate<< endl;
if ( !actdate.isValid() ) return;
-
//flag to indicate if the starting day of the matrix has changed by this call
bool daychanged = false;
@@ -340,16 +344,19 @@ int KODayMatrix::getDayIndexFrom( int x, int y )
void KODayMatrix::calendarIncidenceAdded(Incidence * incidence)
{
+ Q_UNUSED( incidence );
mPendingChanges = true;
}
void KODayMatrix::calendarIncidenceChanged(Incidence * incidence)
{
+ Q_UNUSED( incidence );
mPendingChanges = true;
}
-void KODayMatrix::calendarIncidenceRemoved(Incidence * incidence)
+void KODayMatrix::calendarIncidenceDeleted(Incidence * incidence)
{
+ Q_UNUSED( incidence );
mPendingChanges = true;
}
@@ -406,7 +413,7 @@ void KODayMatrix::mouseMoveEvent( TQMouseEvent *e )
if (mSelInit > tmp) {
mSelEnd = mSelInit;
- if (tmp != mSelStart) {
+ if ( tmp != mSelStart ) {
mSelStart = tmp;
repaint();
}
@@ -414,7 +421,7 @@ void KODayMatrix::mouseMoveEvent( TQMouseEvent *e )
mSelStart = mSelInit;
//repaint only if selection has changed
- if (tmp != mSelEnd) {
+ if ( tmp != mSelEnd ) {
mSelEnd = tmp;
repaint();
}
@@ -669,8 +676,7 @@ void KODayMatrix::paintEvent( TQPaintEvent * )
}
// draw selected days with special color
- // DO NOT specially highlight holidays in selection !
- if (i >= mSelStart && i <= mSelEnd) {
+ if ( i >= mSelStart && i <= mSelEnd && !holiday ) {
p.setPen( TQColor( "white" ) );
}
@@ -678,7 +684,7 @@ void KODayMatrix::paintEvent( TQPaintEvent * )
Qt::AlignHCenter | Qt::AlignVCenter, mDayLabels[i]);
// reset color to actual color
- if (holiday) {
+ if ( holiday ) {
p.setPen(actcol);
}
// reset bold font to plain font
@@ -689,7 +695,7 @@ void KODayMatrix::paintEvent( TQPaintEvent * )
}
}
p.end();
- bitBlt( this, 0, 0, &pm );
+ bitBlt( this, 0, 0, &pm );
}
// ----------------------------------------------------------------------------
@@ -702,3 +708,22 @@ void KODayMatrix::resizeEvent( TQResizeEvent * )
mDaySize.setHeight( sz.height() * 7 / NUMDAYS );
mDaySize.setWidth( sz.width() / 7 );
}
+
+/* static */
+QPair<TQDate,TQDate> KODayMatrix::matrixLimits( const TQDate &month )
+{
+ const KCalendarSystem *calSys = KOGlobals::self()->calendarSystem();
+ TQDate d = month;
+ calSys->setYMD( d, calSys->year( month ), calSys->month( month ), 1 );
+
+ const int dayOfWeek = calSys->dayOfWeek( d );
+ const int weekstart = KGlobal::locale()->weekStartDay();
+
+ d = d.addDays( weekstart - dayOfWeek );
+
+ if ( dayOfWeek == weekstart ) {
+ d = d.addDays( -7 ); // Start on the second line
+ }
+
+ return qMakePair( d, d.addDays( NUMDAYS-1 ) );
+}
diff --git a/korganizer/kodaymatrix.h b/korganizer/kodaymatrix.h
index 7dcf830e..b8354f79 100644
--- a/korganizer/kodaymatrix.h
+++ b/korganizer/kodaymatrix.h
@@ -118,6 +118,11 @@ class KODayMatrix: public TQFrame, public KCal::Calendar::Observer
*/
~KODayMatrix();
+ /** returns the first and last date of the 6*7 matrix that displays @p month
+ * @param month The month we want to get matrix boundaries
+ */
+ static QPair<TQDate,TQDate> matrixLimits( const TQDate &month );
+
/**
Associate a calendar with this day matrix. If there is a calendar, the day
matrix will accept drops and days with events will be highlighted.
@@ -182,7 +187,9 @@ class KODayMatrix: public TQFrame, public KCal::Calendar::Observer
/* reimplmented from KCal::Calendar::Observer */
void calendarIncidenceAdded( Incidence *incidence );
void calendarIncidenceChanged( Incidence *incidence );
- void calendarIncidenceRemoved( Incidence *incidence );
+ void calendarIncidenceDeleted( Incidence *incidence );
+
+ void setUpdateNeeded();
public slots:
/** Recalculates all the flags of the days in the matrix like holidays or events
diff --git a/korganizer/kodialogmanager.cpp b/korganizer/kodialogmanager.cpp
index e17f0340..11f01aa5 100644
--- a/korganizer/kodialogmanager.cpp
+++ b/korganizer/kodialogmanager.cpp
@@ -170,15 +170,15 @@ void KODialogManager::showCategoryEditDialog()
void KODialogManager::showSearchDialog()
{
- if (!mSearchDialog) {
- mSearchDialog = new SearchDialog(mMainView->calendar(),mMainView);
- connect(mSearchDialog,TQT_SIGNAL(showIncidenceSignal(Incidence *)),
- mMainView,TQT_SLOT(showIncidence(Incidence *)));
- connect(mSearchDialog,TQT_SIGNAL(editIncidenceSignal(Incidence *)),
- mMainView,TQT_SLOT(editIncidence(Incidence *)));
- connect(mSearchDialog,TQT_SIGNAL(deleteIncidenceSignal(Incidence *)),
- mMainView, TQT_SLOT(deleteIncidence(Incidence *)));
- connect(mMainView,TQT_SIGNAL(closingDown()),mSearchDialog,TQT_SLOT(reject()));
+ if ( !mSearchDialog ) {
+ mSearchDialog = new SearchDialog( mMainView->calendar(), mMainView );
+ connect( mSearchDialog, TQT_SIGNAL(showIncidenceSignal(Incidence *,const TQDate &)),
+ mMainView, TQT_SLOT(showIncidence(Incidence *,const TQDate &)) );
+ connect( mSearchDialog, TQT_SIGNAL(editIncidenceSignal(Incidence *,const TQDate &)),
+ mMainView, TQT_SLOT(editIncidence(Incidence *,const TQDate &)) );
+ connect( mSearchDialog, TQT_SIGNAL(deleteIncidenceSignal(Incidence *)),
+ mMainView, TQT_SLOT(deleteIncidence(Incidence *)) );
+ connect( mMainView, TQT_SIGNAL(closingDown()),mSearchDialog,TQT_SLOT(reject()) );
}
// make sure the widget is on top again
mSearchDialog->show();
diff --git a/korganizer/koeditoralarms.cpp b/korganizer/koeditoralarms.cpp
index 0a2c7399..8f3cb464 100644
--- a/korganizer/koeditoralarms.cpp
+++ b/korganizer/koeditoralarms.cpp
@@ -25,6 +25,9 @@
#include "koeditoralarms_base.h"
#include "koeditoralarms.h"
+#include "koprefs.h"
+
+#include <libkcal/duration.h>
#include <tqlayout.h>
#include <tqlistview.h>
@@ -35,6 +38,9 @@
#include <tqbuttongroup.h>
#include <tqtextedit.h>
#include <tqwidgetstack.h>
+#include <tqradiobutton.h>
+#include <tqtooltip.h>
+#include <tqwhatsthis.h>
#include <kurlrequester.h>
#include <klocale.h>
@@ -48,22 +54,46 @@
class AlarmListViewItem : public QListViewItem
{
public:
- AlarmListViewItem( TQListView *parent, KCal::Alarm *alarm );
+ AlarmListViewItem( TQListView *parent, KCal::Alarm *alarm, const TQCString &inctype );
virtual ~AlarmListViewItem();
KCal::Alarm *alarm() const { return mAlarm; }
void construct();
enum AlarmViewColumns { ColAlarmType=0, ColAlarmOffset, ColAlarmRepeat };
+
protected:
KCal::Alarm *mAlarm;
+
+ private:
+ TQCString mIncType;
};
-AlarmListViewItem::AlarmListViewItem( TQListView *parent, KCal::Alarm *alarm )
- : TQListViewItem( parent )
+AlarmListViewItem::AlarmListViewItem( TQListView *parent, KCal::Alarm *alarm,
+ const TQCString &inctype )
+ : TQListViewItem( parent ), mIncType( inctype )
{
if ( alarm ) {
mAlarm = new KCal::Alarm( *alarm );
} else {
mAlarm = new KCal::Alarm( 0 );
+ mAlarm->setType( KCal::Alarm::Display );
+ int duration; // in secs
+ switch( KOPrefs::instance()->mReminderTimeUnits ) {
+ default:
+ case 0: // mins
+ duration = KOPrefs::instance()->mReminderTime * 60;
+ break;
+ case 1: // hours
+ duration = KOPrefs::instance()->mReminderTime * 60 * 60;
+ break;
+ case 2: // days
+ duration = KOPrefs::instance()->mReminderTime * 60 * 60 * 24;
+ break;
+ }
+ if ( mIncType == "Event" ) {
+ mAlarm->setStartOffset( KCal::Duration( -duration ) );
+ } else {
+ mAlarm->setEndOffset( KCal::Duration( -duration ) );
+ }
}
construct();
}
@@ -102,19 +132,33 @@ void AlarmListViewItem::construct()
int offset = 0;
if ( mAlarm->hasStartOffset() ) {
offset = mAlarm->startOffset().asSeconds();
- if ( offset < 0 ) {
- offsetstr = i18n("N days/hours/minutes before/after the start/end", "%1 before the start");
+ if ( offset <= 0 ) {
+ offsetstr = i18n( "N days/hours/minutes before/after the start/end",
+ "%1 before the start" );
offset = -offset;
} else {
- offsetstr = i18n("N days/hours/minutes before/after the start/end", "%1 after the start");
+ offsetstr = i18n( "N days/hours/minutes before/after the start/end",
+ "%1 after the start" );
}
} else if ( mAlarm->hasEndOffset() ) {
offset = mAlarm->endOffset().asSeconds();
- if ( offset < 0 ) {
- offsetstr = i18n("N days/hours/minutes before/after the start/end", "%1 before the end");
+ if ( offset <= 0 ) {
+ if ( mIncType == "Todo" ) {
+ offsetstr = i18n( "N days/hours/minutes before/after the due date",
+ "%1 before the to-do is due" );
+ } else {
+ offsetstr = i18n( "N days/hours/minutes before/after the start/end",
+ "%1 before the end" );
+ }
offset = -offset;
} else {
- offsetstr = i18n("N days/hours/minutes before/after the start/end", "%1 after the end");
+ if ( mIncType == "Todo" ) {
+ offsetstr = i18n( "N days/hours/minutes before/after the due date",
+ "%1 after the to-do is due" );
+ } else {
+ offsetstr = i18n( "N days/hours/minutes before/after the start/end",
+ "%1 after the end" );
+ }
}
}
@@ -143,11 +187,23 @@ void AlarmListViewItem::construct()
}
-KOEditorAlarms::KOEditorAlarms( KCal::Alarm::List *alarms, TQWidget *parent,
+KOEditorAlarms::KOEditorAlarms( const TQCString &type,
+ KCal::Alarm::List *alarms, TQWidget *parent,
const char *name )
- : KDialogBase( parent, name, true, i18n("Edit Reminders"), Ok | Cancel ), mAlarms( alarms ),mCurrentItem(0L)
+ : KDialogBase( parent, name, true, i18n("Advanced Reminders"), Ok | Cancel ),
+ mType( type ), mAlarms( alarms ),mCurrentItem( 0 )
{
+ if ( mType != "Todo" ) {
+ // only Todos and Events can have reminders
+ mType = "Event";
+ }
setMainWidget( mWidget = new KOEditorAlarms_base( this ) );
+
+ // The text is set here, and not in the UI file, because the i18n context is not
+ // properly extracted from the UI file.
+ mWidget->mAddButton->setText( i18n( "Add a new alarm to the alarm list.", "&Add" ) );
+
+ mWidget->mAlarmList->setResizeMode( TQListView::LastColumn );
mWidget->mAlarmList->setColumnWidthMode( 0, TQListView::Maximum );
mWidget->mAlarmList->setColumnWidthMode( 1, TQListView::Maximum );
connect( mWidget->mAlarmList, TQT_SIGNAL( selectionChanged( TQListViewItem * ) ),
@@ -171,6 +227,11 @@ KOEditorAlarms::KOEditorAlarms( KCal::Alarm::List *alarms, TQWidget *parent,
connect( mWidget->mEmailText, TQT_SIGNAL( textChanged() ), TQT_SLOT( changed() ) );
init();
+
+ //TODO: backport email reminders from trunk
+ mWidget->mTypeEmailRadio->hide(); //email reminders not implemented yet
+
+ mWidget->setMinimumSize( 500, 500 );
}
KOEditorAlarms::~KOEditorAlarms()
@@ -180,7 +241,16 @@ KOEditorAlarms::~KOEditorAlarms()
void KOEditorAlarms::changed()
{
if ( !mInitializing && mCurrentItem ) {
- writeAlarm( mCurrentItem->alarm() );
+ KCal::Alarm *alarm = mCurrentItem->alarm();
+
+ // Based on settings, provide default sound file for audio alarms
+ if ( alarm->audioFile().isEmpty() &&
+ KOPrefs::instance()->defaultAudioFileReminders() ) {
+ alarm->setAudioFile( KOPrefs::instance()->audioFilePath() );
+ mWidget->mSoundFile->setURL( KOPrefs::instance()->audioFilePath() );
+ }
+
+ writeAlarm( alarm );
mCurrentItem->construct();
}
}
@@ -194,6 +264,11 @@ void KOEditorAlarms::readAlarm( KCal::Alarm *alarm )
// Offsets
int offset;
int beforeafterpos = 0;
+ if ( mType == "Todo" ) {
+ if ( !alarm->hasStartOffset() ) {
+ beforeafterpos = 2;
+ }
+ }
if ( alarm->hasEndOffset() ) {
beforeafterpos = 2;
offset = alarm->endOffset().asSeconds();
@@ -202,7 +277,7 @@ void KOEditorAlarms::readAlarm( KCal::Alarm *alarm )
offset = alarm->startOffset().asSeconds();
}
// Negative offset means before the start/end...
- if ( offset < 0 ) {
+ if ( offset <= 0 ) {
offset = -offset;
} else {
++beforeafterpos;
@@ -229,7 +304,7 @@ void KOEditorAlarms::readAlarm( KCal::Alarm *alarm )
mWidget->mRepeats->setChecked( alarm->repeatCount()>0 );
if ( alarm->repeatCount()>0 ) {
mWidget->mRepeatCount->setValue( alarm->repeatCount() );
- mWidget->mRepeatInterval->setValue( alarm->snoozeTime() );
+ mWidget->mRepeatInterval->setValue( alarm->snoozeTime().asSeconds() / 60 ); // show as minutes
}
switch ( alarm->type() ) {
@@ -290,7 +365,7 @@ void KOEditorAlarms::writeAlarm( KCal::Alarm *alarm )
// Repeating
if ( mWidget->mRepeats->isChecked() ) {
alarm->setRepeatCount( mWidget->mRepeatCount->value() );
- alarm->setSnoozeTime( mWidget->mRepeatInterval->value() );
+ alarm->setSnoozeTime( KCal::Duration( mWidget->mRepeatInterval->value() * 60 ) ); // convert back to seconds
} else {
alarm->setRepeatCount( 0 );
}
@@ -333,6 +408,9 @@ void KOEditorAlarms::selectionChanged( TQListViewItem *listviewitem )
void KOEditorAlarms::slotOk()
{
+ // save the current item settings, if any
+ changed();
+
// copy the mAlarms list
if ( mAlarms ) {
mAlarms->clear();
@@ -350,17 +428,15 @@ void KOEditorAlarms::slotOk()
void KOEditorAlarms::slotAdd()
{
- mCurrentItem = new AlarmListViewItem( mWidget->mAlarmList, 0 );
+ mCurrentItem = new AlarmListViewItem( mWidget->mAlarmList, 0, mType );
mWidget->mAlarmList->setCurrentItem( mCurrentItem );
-// selectionChanged( mCurrentItem );
}
void KOEditorAlarms::slotDuplicate()
{
if ( mCurrentItem ) {
- mCurrentItem = new AlarmListViewItem( mWidget->mAlarmList, mCurrentItem->alarm() );
+ mCurrentItem = new AlarmListViewItem( mWidget->mAlarmList, mCurrentItem->alarm(), mType );
mWidget->mAlarmList->setCurrentItem( mCurrentItem );
-// selectionChanged( mCurrentItem );
}
}
@@ -370,16 +446,36 @@ void KOEditorAlarms::slotRemove()
delete mCurrentItem;
mCurrentItem = dynamic_cast<AlarmListViewItem*>( mWidget->mAlarmList->currentItem() );
mWidget->mAlarmList->setSelected( mCurrentItem, true );
-
}
}
void KOEditorAlarms::init()
{
mInitializing = true;
+
+ // Tweak some UI stuff depending on the Incidence type
+ if ( mType == "Todo" ) {
+ // Replace before/after end datetime with before/after due datetime
+ mWidget->mBeforeAfter->clear();
+ mWidget->mBeforeAfter->insertItem( i18n( "before the to-do starts" ), 0 );
+ mWidget->mBeforeAfter->insertItem( i18n( "after the to-do starts" ), 1 );
+ mWidget->mBeforeAfter->insertItem( i18n( "before the to-do is due" ), 2 );
+ mWidget->mBeforeAfter->insertItem( i18n( "after the to-do is due" ), 3 );
+ TQToolTip::add(
+ mWidget->mBeforeAfter,
+ i18n( "Select the reminder trigger relative to the start or due time" ) );
+ TQWhatsThis::add(
+ mWidget->mBeforeAfter,
+ i18n( "Use this combobox to specify if you want the reminder to "
+ "trigger before or after the start or due time." ) );
+
+ mWidget->mBeforeAfter->setCurrentItem( 2 ); // default is before due start
+ }
+
+ // Fill-in existing alarms
KCal::Alarm::List::ConstIterator it;
for ( it = mAlarms->begin(); it != mAlarms->end(); ++it ) {
- new AlarmListViewItem( mWidget->mAlarmList, *it );
+ new AlarmListViewItem( mWidget->mAlarmList, *it, mType );
}
mWidget->mAlarmList->setSelected( mWidget->mAlarmList->firstChild(), true );
mInitializing = false;
diff --git a/korganizer/koeditoralarms.h b/korganizer/koeditoralarms.h
index ed01d656..971df799 100644
--- a/korganizer/koeditoralarms.h
+++ b/korganizer/koeditoralarms.h
@@ -35,7 +35,8 @@ class KOEditorAlarms : public KDialogBase
{
Q_OBJECT
public:
- KOEditorAlarms( KCal::Alarm::List *alarms, TQWidget *parent = 0,
+ KOEditorAlarms( const TQCString &type,
+ KCal::Alarm::List *alarms, TQWidget *parent = 0,
const char *name = 0 );
~KOEditorAlarms();
@@ -46,11 +47,14 @@ class KOEditorAlarms : public KDialogBase
void slotRemove();
void changed();
void selectionChanged( TQListViewItem *listviewitem );
+
protected:
void init();
void readAlarm( KCal::Alarm *alarm );
void writeAlarm( KCal::Alarm *alarm );
+
private:
+ TQCString mType; // as in the Incidence::type
KCal::Alarm::List *mAlarms;
KOEditorAlarms_base *mWidget;
bool mInitializing;
diff --git a/korganizer/koeditoralarms_base.ui b/korganizer/koeditoralarms_base.ui
index 68e8d5bc..1da10440 100644
--- a/korganizer/koeditoralarms_base.ui
+++ b/korganizer/koeditoralarms_base.ui
@@ -45,6 +45,12 @@
<property name="name">
<cstring>mAlarmOffset</cstring>
</property>
+ <property name="maxValue">
+ <number>99999</number>
+ </property>
+ <property name="minValue">
+ <number>0</number>
+ </property>
<property name="sizePolicy">
<sizepolicy>
<hsizetype>4</hsizetype>
@@ -381,7 +387,7 @@
<cstring>mSoundFile</cstring>
</property>
<property name="filter">
- <string>audio/x-wav audio/x-mp3 application/ogg</string>
+ <string>audio/x-wav audio/x-mp3 application/ogg</string>
</property>
</widget>
<spacer>
@@ -535,7 +541,7 @@
<cstring>mRemoveButton</cstring>
</property>
<property name="text">
- <string>&amp;Remove...</string>
+ <string>&amp;Remove</string>
</property>
</widget>
<widget class="QPushButton" row="0" column="1">
@@ -543,7 +549,7 @@
<cstring>mAddButton</cstring>
</property>
<property name="text">
- <string>&amp;Add</string>
+ <string></string>
</property>
</widget>
<widget class="QPushButton" row="1" column="1">
diff --git a/korganizer/koeditorattachments.cpp b/korganizer/koeditorattachments.cpp
index adcd871e..99d775e6 100644
--- a/korganizer/koeditorattachments.cpp
+++ b/korganizer/koeditorattachments.cpp
@@ -25,15 +25,19 @@
#include "koeditorattachments.h"
+#include <libkcal/attachmenthandler.h>
#include <libkcal/incidence.h>
#include <libkdepim/kpimurlrequesterdlg.h>
#include <libkdepim/kfileio.h>
+#include <libkdepim/kdepimprotocols.h>
+#include <libkdepim/maillistdrag.h>
+#include <libkdepim/kvcarddrag.h>
+#include <libkdepim/kdepimprotocols.h>
#include <klocale.h>
#include <kdebug.h>
#include <kmdcodec.h>
#include <kmessagebox.h>
-#include <kiconview.h>
#include <krun.h>
#include <kurldrag.h>
#include <ktempfile.h>
@@ -45,7 +49,13 @@
#include <kstdaction.h>
#include <kactioncollection.h>
#include <kpopupmenu.h>
+#include <kprotocolinfo.h>
+#include <klineedit.h>
+#include <kseparator.h>
+#include <kurlrequester.h>
+#include <libkmime/kmime_message.h>
+#include <tqcheckbox.h>
#include <tqfile.h>
#include <tqlabel.h>
#include <tqlayout.h>
@@ -58,7 +68,7 @@
#include <tqclipboard.h>
#include <cassert>
-#include <set>
+#include <cstdlib>
class AttachmentListItem : public KIconViewItem
{
@@ -69,7 +79,8 @@ class AttachmentListItem : public KIconViewItem
if ( att ) {
mAttachment = new KCal::Attachment( *att );
} else {
- mAttachment = new KCal::Attachment( TQString::null );
+ mAttachment = new KCal::Attachment( '\0' ); //use the non-uri constructor
+ //as we want inline by default
}
readAttachment();
setDragEnabled( true );
@@ -77,112 +88,364 @@ class AttachmentListItem : public KIconViewItem
~AttachmentListItem() { delete mAttachment; }
KCal::Attachment *attachment() const { return mAttachment; }
+ const TQString uri() const
+ {
+ return mAttachment->uri();
+ }
void setUri( const TQString &uri )
{
mAttachment->setUri( uri );
readAttachment();
}
- void setData( const char *base64 )
+ void setData( const TQByteArray data )
{
- mAttachment->setData( base64 );
+ mAttachment->setDecodedData( data );
readAttachment();
}
+ const TQString mimeType() const
+ {
+ return mAttachment->mimeType();
+ }
void setMimeType( const TQString &mime )
{
mAttachment->setMimeType( mime );
readAttachment();
}
+ const TQString label() const
+ {
+ return mAttachment->label();
+ }
void setLabel( const TQString &label )
{
mAttachment->setLabel( label );
readAttachment();
}
-
+ bool isBinary() const
+ {
+ return mAttachment->isBinary();
+ }
+ TQPixmap icon() const
+ {
+ return icon( KMimeType::mimeType( mAttachment->mimeType() ),
+ mAttachment->uri() );
+ }
+ static TQPixmap icon( KMimeType::Ptr mimeType, const TQString &uri )
+ {
+ TQString iconStr = mimeType->icon( uri, false );
+ return KGlobal::iconLoader()->loadIcon( iconStr, KIcon::Small );
+ }
void readAttachment()
{
- if ( mAttachment->isUri() )
- setText( mAttachment->uri() );
- else {
- if ( mAttachment->label().isEmpty() )
- setText( i18n("[Binary data]") );
- else
- setText( mAttachment->label() );
+ if ( mAttachment->label().isEmpty() ) {
+ if ( mAttachment->isUri() ) {
+ setText( mAttachment->uri() );
+ } else {
+ setText( i18n( "[Binary data]" ) );
+ }
+ } else {
+ setText( mAttachment->label() );
}
- KMimeType::Ptr mt = KMimeType::mimeType( mAttachment->mimeType() );
- if ( mt ) {
- const TQString iconName( mt->icon( TQString(), false ) );
- TQPixmap pix = KGlobal::iconLoader( )->loadIcon( iconName, KIcon::Small );
- if ( pix.isNull() )
- pix = KGlobal::iconLoader( )->loadIcon( "unknown", KIcon::Small );
- if ( !pix.isNull() )
- setPixmap( pix );
+ if ( mAttachment->mimeType().isEmpty() ||
+ !( KMimeType::mimeType( mAttachment->mimeType() ) ) ) {
+ KMimeType::Ptr mimeType;
+ if ( mAttachment->isUri() ) {
+ mimeType = KMimeType::findByURL( mAttachment->uri() );
+ } else {
+ mimeType = KMimeType::findByContent( mAttachment->decodedData() );
+ }
+ mAttachment->setMimeType( mimeType->name() );
}
+
+ setPixmap( icon() );
}
private:
KCal::Attachment *mAttachment;
};
-class AttachmentIconView : public KIconView
-{
- friend class KOEditorAttachments;
- public:
- AttachmentIconView( KOEditorAttachments* parent=0 )
- :KIconView( parent ),
- mParent( parent )
- {
- setAcceptDrops( true );
- setSelectionMode( TQIconView::Extended );
- setMode( KIconView::Select );
- setItemTextPos( TQIconView::Right );
- setArrangement( TQIconView::LeftToRight );
- setMaxItemWidth( QMAX(maxItemWidth(), 250) );
- setMinimumHeight( QMAX(fontMetrics().height(), 16) + 12 );
- }
- ~AttachmentIconView()
- {
- for ( std::set<KTempDir*>::iterator it = mTempDirs.begin() ; it != mTempDirs.end() ; ++it ) {
- delete *it;
- }
- }
- protected:
- TQDragObject * dragObject()
- {
- KURL::List urls;
- for ( TQIconViewItem *it = firstItem( ); it; it = it->nextItem( ) ) {
- if ( !it->isSelected() ) continue;
- AttachmentListItem * item = dynamic_cast<AttachmentListItem*>( it );
- if ( !item ) return 0;
- KCal::Attachment * att = item->attachment();
- assert( att );
- KURL url;
- if ( att->isUri() ) {
- url.setPath( att->uri() );
- } else {
- KTempDir * tempDir = new KTempDir(); // will be deleted on editor close
- tempDir->setAutoDelete( true );
- mTempDirs.insert( tempDir );
- TQByteArray encoded;
- encoded.duplicate( att->data(), strlen(att->data()) );
- TQByteArray decoded;
- KCodecs::base64Decode( encoded, decoded );
- const TQString fileName = tempDir->name( ) + "/" + att->label();
- KPIM::kByteArrayToFile( decoded, fileName, false, false, false );
- url.setPath( fileName );
- }
- urls << url;
- }
- KURLDrag *drag = new KURLDrag( urls, this );
- return drag;
- }
- void contentsDropEvent( TQDropEvent* event )
- {
- mParent->handlePasteOrDrop( event );
+AttachmentEditDialog::AttachmentEditDialog( AttachmentListItem *item,
+ TQWidget *parent )
+ : KDialogBase ( Plain, i18n( "Add Attachment" ), Ok|Cancel, Ok, parent, 0, false, false ),
+ mItem( item ), mURLRequester( 0 )
+{
+ TQFrame *topFrame = plainPage();
+ TQVBoxLayout *vbl = new TQVBoxLayout( topFrame, 0, spacingHint() );
+
+ TQGridLayout *grid = new TQGridLayout();
+ grid->setColStretch( 0, 0 );
+ grid->setColStretch( 1, 0 );
+ grid->setColStretch( 2, 1 );
+ vbl->addLayout( grid );
+
+ mIcon = new TQLabel( topFrame );
+ mIcon->setPixmap( item->icon() );
+ grid->addWidget( mIcon, 0, 0 );
+
+ mLabelEdit = new KLineEdit( topFrame );
+ mLabelEdit->setText( item->label().isEmpty() ? item->uri() : item->label() );
+ mLabelEdit->setClickMessage( i18n( "Attachment name" ) );
+ TQToolTip::add( mLabelEdit, i18n( "Give the attachment a name" ) );
+ TQWhatsThis::add( mLabelEdit,
+ i18n( "Type any string you desire here for the name of the attachment" ) );
+ grid->addMultiCellWidget( mLabelEdit, 0, 0, 1, 2 );
+
+ KSeparator *sep = new KSeparator( TQt::Horizontal, topFrame );
+ grid->addMultiCellWidget( sep, 1, 1, 0, 2 );
+
+ TQLabel *label = new TQLabel( i18n( "Type:" ), topFrame );
+ grid->addWidget( label, 2, 0 );
+ TQString typecomment = item->mimeType().isEmpty() ?
+ i18n( "Unknown" ) :
+ KMimeType::mimeType( item->mimeType() )->comment();
+ mTypeLabel = new TQLabel( typecomment, topFrame );
+ grid->addWidget( mTypeLabel, 2, 1 );
+ mMimeType = KMimeType::mimeType( item->mimeType() );
+
+ mInline = new TQCheckBox( i18n( "Store attachment inline" ), topFrame );
+ grid->addMultiCellWidget( mInline, 3, 3, 0, 2 );
+ mInline->setChecked( item->isBinary() );
+ TQToolTip::add( mInline, i18n( "Store the attachment file inside the calendar" ) );
+ TQWhatsThis::add(
+ mInline,
+ i18n( "Checking this option will cause the attachment to be stored inside "
+ "your calendar, which can take a lot of space depending on the size "
+ "of the attachment. If this option is not checked, then only a link "
+ "pointing to the attachment will be stored. Do not use a link for "
+ "attachments that change often or may be moved (or removed) from "
+ "their current location." ) );
+
+ if ( item->attachment()->isUri() || !item->attachment()->data() ) {
+ label = new TQLabel( i18n( "Location:" ), topFrame );
+ grid->addWidget( label, 4, 0 );
+ mURLRequester = new KURLRequester( item->uri(), topFrame );
+ TQToolTip::add( mURLRequester, i18n( "Provide a location for the attachment file" ) );
+ TQWhatsThis::add(
+ mURLRequester,
+ i18n( "Enter the path to the attachment file or use the "
+ "file browser by pressing the adjacent button" ) );
+ grid->addMultiCellWidget( mURLRequester, 4, 4, 1, 2 );
+ connect( mURLRequester, TQT_SIGNAL(urlSelected(const TQString &)),
+ TQT_SLOT(urlSelected(const TQString &)) );
+ connect( mURLRequester, TQT_SIGNAL( textChanged( const TQString& ) ),
+ TQT_SLOT( urlChanged( const TQString& ) ) );
+ urlChanged( item->uri() );
+ } else {
+ uint size = item->attachment()->size();
+ grid->addWidget( new TQLabel( i18n( "Size:" ), topFrame ), 4, 0 );
+ grid->addWidget( new TQLabel( TQString::fromLatin1( "%1 (%2)" ).
+ arg( KIO::convertSize( size ) ).
+ arg( KGlobal::locale()->formatNumber(
+ size, 0 ) ), topFrame ), 4, 2 );
+ }
+ vbl->addStretch( 10 );
+}
+
+void AttachmentEditDialog::slotApply()
+{
+ if ( !mLabelEdit->text().isEmpty() ) {
+ mItem->setLabel( mLabelEdit->text() );
+ } else {
+ if ( mURLRequester ) {
+ KURL url( mURLRequester->url() );
+ if ( url.isLocalFile() ) {
+ mItem->setLabel( url.fileName() );
+ } else {
+ mItem->setLabel( url.url() );
+ }
+ }
+ }
+ if ( mItem->label().isEmpty() ) {
+ mItem->setLabel( i18n( "New attachment" ) );
+ }
+ mItem->setMimeType( mMimeType->name() );
+ if ( mURLRequester ) {
+ KURL url( mURLRequester->url() );
+
+ TQString correctedUrl = mURLRequester->url();
+ if ( !url.isValid() ) {
+ // If the user used KURLRequester's KURLCompletion
+ // (used the line edit instead of the file dialog)
+ // the returned url is not absolute and is always relative
+ // to the home directory (not pwd), so we must prepend home
+
+ correctedUrl = TQDir::home().filePath( mURLRequester->url() );
+ url = KURL( correctedUrl );
+ if ( url.isValid() ) {
+ urlSelected( correctedUrl );
+ mItem->setMimeType( mMimeType->name() );
+ }
+ }
+
+ if ( mInline->isChecked() ) {
+ TQString tmpFile;
+ if ( KIO::NetAccess::download( correctedUrl, tmpFile, this ) ) {
+ TQFile f( tmpFile );
+ if ( !f.open( IO_ReadOnly ) ) {
+ return;
}
- private:
- std::set<KTempDir*> mTempDirs;
- KOEditorAttachments* mParent;
-};
+ TQByteArray data = f.readAll();
+ f.close();
+ mItem->setData( data );
+ }
+ KIO::NetAccess::removeTempFile( tmpFile );
+ } else {
+ mItem->setUri( url.url() );
+ }
+ }
+}
+
+void AttachmentEditDialog::accept()
+{
+ slotApply();
+ KDialog::accept();
+}
+
+void AttachmentEditDialog::urlChanged( const TQString &url )
+{
+ enableButton( Ok, !url.isEmpty() );
+}
+
+void AttachmentEditDialog::urlSelected( const TQString &url )
+{
+ KURL kurl( url );
+ mMimeType = KMimeType::findByURL( kurl );
+ mTypeLabel->setText( mMimeType->comment() );
+ mIcon->setPixmap( AttachmentListItem::icon( mMimeType, kurl.path() ) );
+}
+
+AttachmentIconView::AttachmentIconView( KOEditorAttachments* parent )
+ : KIconView( parent ),
+ mParent( parent )
+{
+ setSelectionMode( TQIconView::Extended );
+ setMode( KIconView::Select );
+ setItemTextPos( TQIconView::Right );
+ setArrangement( TQIconView::LeftToRight );
+ setMaxItemWidth( QMAX(maxItemWidth(), 250) );
+ setMinimumHeight( QMAX(fontMetrics().height(), 16) + 12 );
+
+ connect( this, TQT_SIGNAL( dropped ( TQDropEvent *, const TQValueList<TQIconDragItem> & ) ),
+ this, TQT_SLOT( handleDrop( TQDropEvent *, const TQValueList<TQIconDragItem> & ) ) );
+}
+
+KURL AttachmentIconView::tempFileForAttachment( KCal::Attachment *attachment )
+{
+ if ( mTempFiles.contains( attachment ) ) {
+ return mTempFiles[attachment];
+ }
+ TQStringList patterns = KMimeType::mimeType( attachment->mimeType() )->patterns();
+
+ KTempFile *file;
+ if ( !patterns.empty() ) {
+ file = new KTempFile( TQString::null,
+ TQString( patterns.first() ).remove( '*' ),0600 );
+ } else {
+ file = new KTempFile( TQString::null, TQString::null, 0600 );
+ }
+ file->setAutoDelete( true );
+ file->file()->open( IO_WriteOnly );
+ TQTextStream stream( file->file() );
+ stream.writeRawBytes( attachment->decodedData().data(), attachment->size() );
+ KURL url( file->name() );
+ mTempFiles.insert( attachment, url );
+ file->close();
+ return mTempFiles[attachment];
+}
+
+TQDragObject *AttachmentIconView::mimeData()
+{
+ // create a list of the URL:s that we want to drag
+ KURL::List urls;
+ TQStringList labels;
+ for ( TQIconViewItem *it = firstItem(); it; it = it->nextItem() ) {
+ if ( it->isSelected() ) {
+ AttachmentListItem *item = static_cast<AttachmentListItem *>( it );
+ if ( item->isBinary() ) {
+ urls.append( tempFileForAttachment( item->attachment() ) );
+ } else {
+ urls.append( item->uri() );
+ }
+ labels.append( KURL::encode_string( item->label() ) );
+ }
+ }
+ if ( selectionMode() == TQIconView::NoSelection ) {
+ AttachmentListItem *item = static_cast<AttachmentListItem *>( currentItem() );
+ if ( item ) {
+ urls.append( item->uri() );
+ labels.append( KURL::encode_string( item->label() ) );
+ }
+ }
+
+ TQMap<TQString, TQString> metadata;
+ metadata["labels"] = labels.join( ":" );
+
+ KURLDrag *drag = new KURLDrag( urls, metadata );
+ return drag;
+}
+
+AttachmentIconView::~AttachmentIconView()
+{
+ for ( std::set<KTempDir*>::iterator it = mTempDirs.begin() ; it != mTempDirs.end() ; ++it ) {
+ delete *it;
+ }
+}
+
+TQDragObject * AttachmentIconView::dragObject()
+{
+ KURL::List urls;
+ for ( TQIconViewItem *it = firstItem( ); it; it = it->nextItem( ) ) {
+ if ( !it->isSelected() ) continue;
+ AttachmentListItem * item = dynamic_cast<AttachmentListItem*>( it );
+ if ( !item ) return 0;
+ KCal::Attachment * att = item->attachment();
+ assert( att );
+ KURL url;
+ if ( att->isUri() ) {
+ url.setPath( att->uri() );
+ } else {
+ KTempDir *tempDir = new KTempDir(); // will be deleted on editor close
+ tempDir->setAutoDelete( true );
+ mTempDirs.insert( tempDir );
+ TQByteArray encoded;
+ encoded.duplicate( att->data(), strlen( att->data() ) );
+ TQByteArray decoded;
+ KCodecs::base64Decode( encoded, decoded );
+ const TQString fileName = tempDir->name( ) + '/' + att->label();
+ KPIM::kByteArrayToFile( decoded, fileName, false, false, false );
+ url.setPath( fileName );
+ }
+ urls << url;
+ }
+ KURLDrag *drag = new KURLDrag( urls, this );
+ return drag;
+}
+
+void AttachmentIconView::handleDrop( TQDropEvent *event, const TQValueList<TQIconDragItem> & list )
+{
+ Q_UNUSED( list );
+ mParent->handlePasteOrDrop( event );
+}
+
+
+void AttachmentIconView::dragMoveEvent( TQDragMoveEvent *event )
+{
+ mParent->dragMoveEvent( event );
+}
+
+void AttachmentIconView::contentsDragMoveEvent( TQDragMoveEvent *event )
+{
+ mParent->dragMoveEvent( event );
+}
+
+void AttachmentIconView::contentsDragEnterEvent( TQDragEnterEvent *event )
+{
+ mParent->dragMoveEvent( event );
+}
+
+void AttachmentIconView::dragEnterEvent( TQDragEnterEvent *event )
+{
+ mParent->dragEnterEvent( event );
+}
KOEditorAttachments::KOEditorAttachments( int spacing, TQWidget *parent,
const char *name )
@@ -206,44 +469,51 @@ KOEditorAttachments::KOEditorAttachments( int spacing, TQWidget *parent,
connect( mAttachments, TQT_SIGNAL(contextMenuRequested(TQIconViewItem*,const TQPoint&)),
TQT_SLOT(contextMenu(TQIconViewItem*,const TQPoint&)) );
- mAddMenu = new KPopupMenu( this );
+ TQPushButton *addButton = new TQPushButton( this );
+ addButton->setIconSet( SmallIconSet( "add" ) );
+ TQToolTip::add( addButton, i18n( "Add an attachment" ) );
+ TQWhatsThis::add( addButton,
+ i18n( "Shows a dialog used to select an attachment "
+ "to add to this event or to-do as link or as "
+ "inline data." ) );
+ topLayout->addWidget( addButton );
+ connect( addButton, TQT_SIGNAL(clicked()), TQT_SLOT(slotAdd()) );
+
+ mRemoveBtn = new TQPushButton( this );
+ mRemoveBtn->setIconSet( SmallIconSet( "remove" ) );
+ TQToolTip::add( mRemoveBtn, i18n("&Remove") );
+ TQWhatsThis::add( mRemoveBtn,
+ i18n("Removes the attachment selected in the list above "
+ "from this event or to-do.") );
+ topLayout->addWidget( mRemoveBtn );
+ connect( mRemoveBtn, TQT_SIGNAL(clicked()), TQT_SLOT(slotRemove()) );
+
mContextMenu = new KPopupMenu( this );
KActionCollection* ac = new KActionCollection( this, this );
- mOpenAction = new KAction( i18n("View"), 0, this, TQT_SLOT(slotShow()), ac );
+ mOpenAction = new KAction( i18n("Open"), 0, this, TQT_SLOT(slotShow()), ac );
mOpenAction->plug( mContextMenu );
+
+ mSaveAsAction = new KAction( i18n( "Save As..." ), 0, this, TQT_SLOT(slotSaveAs()), ac );
+ mSaveAsAction->plug( mContextMenu );
mContextMenu->insertSeparator();
- mCopyAction = KStdAction::copy(this, TQT_SLOT(slotCopy( ) ), ac );
+ mCopyAction = KStdAction::copy(this, TQT_SLOT(slotCopy()), ac );
mCopyAction->plug( mContextMenu );
- mCutAction = KStdAction::cut(this, TQT_SLOT(slotCut( ) ), ac );
+ mCutAction = KStdAction::cut(this, TQT_SLOT(slotCut()), ac );
mCutAction->plug( mContextMenu );
- KAction *action = KStdAction::paste(this, TQT_SLOT(slotPaste( ) ), ac );
+ KAction *action = KStdAction::paste(this, TQT_SLOT(slotPaste()), ac );
action->plug( mContextMenu );
+ mContextMenu->insertSeparator();
- action = new KAction( i18n("&Attach File..."), 0, this, TQT_SLOT(slotAddData()), ac );
- action->setWhatsThis( i18n("Shows a dialog used to select an attachment "
- "to add to this event or to-do as link as inline data.") );
- action->plug( mAddMenu );
- action = new KAction( i18n("Attach &Link..."), 0, this, TQT_SLOT(slotAdd()), ac );
- action->setWhatsThis( i18n("Shows a dialog used to select an attachment "
- "to add to this event or to-do as link.") );
- action->plug( mAddMenu );
+ mDeleteAction = new KAction( i18n( "&Remove" ), 0, this, TQT_SLOT(slotRemove()), ac );
+ mDeleteAction->plug( mContextMenu );
+ mDeleteAction->setShortcut( Key_Delete );
+ mContextMenu->insertSeparator();
- TQPushButton *addButton = new TQPushButton( this );
- addButton->setIconSet( SmallIconSet( "add" ) );
- addButton->setPopup( mAddMenu );
- topLayout->addWidget( addButton );
-
- mRemoveBtn = new TQPushButton( this );
- mRemoveBtn->setIconSet( SmallIconSet( "remove" ) );
- TQToolTip::add( mRemoveBtn, i18n("&Remove") );
- TQWhatsThis::add( mRemoveBtn,
- i18n("Removes the attachment selected in the list above "
- "from this event or to-do.") );
- topLayout->addWidget( mRemoveBtn );
- connect( mRemoveBtn, TQT_SIGNAL( clicked() ), TQT_SLOT( slotRemove() ) );
+ mEditAction = new KAction( i18n( "&Properties..." ), 0, this, TQT_SLOT(slotEdit()), ac );
+ mEditAction->plug( mContextMenu );
selectionChanged();
setAcceptDrops( true );
@@ -258,26 +528,106 @@ bool KOEditorAttachments::hasAttachments()
return mAttachments->count() != 0;
}
+void KOEditorAttachments::dragMoveEvent( TQDragMoveEvent *event )
+{
+ event->accept( KURLDrag::canDecode( event ) ||
+ TQTextDrag::canDecode( event ) ||
+ KPIM::MailListDrag::canDecode( event ) ||
+ KVCardDrag::canDecode( event ) );
+}
+
void KOEditorAttachments::dragEnterEvent( TQDragEnterEvent* event )
{
- event->accept( KURLDrag::canDecode( event ) | TQTextDrag::canDecode( event ) );
+ dragMoveEvent( event );
}
void KOEditorAttachments::handlePasteOrDrop( TQMimeSource* source )
{
KURL::List urls;
- TQString text;
- if ( KURLDrag::decode( source, urls ) ) {
- const bool asUri = KMessageBox::questionYesNo( this,
- i18n("Do you want to link to the attachments, or include them in the event?"),
- i18n("Attach as link?"), i18n("As Link"), i18n("As File") ) == KMessageBox::Yes;
- for ( KURL::List::ConstIterator it = urls.begin(); it != urls.end(); ++it ) {
- addAttachment( (*it).url(), TQString::null, asUri );
- }
- } else if ( TQTextDrag::decode( source, text ) ) {
- TQStringList lst = TQStringList::split( '\n', text );
- for ( TQStringList::ConstIterator it = lst.begin(); it != lst.end(); ++it ) {
- addAttachment( (*it) );
+ bool probablyWeHaveUris = false;
+ bool weCanCopy = true;
+ TQStringList labels;
+
+ if ( KVCardDrag::canDecode( source ) ) {
+ KABC::Addressee::List addressees;
+ KVCardDrag::decode( source, addressees );
+ for ( KABC::Addressee::List::ConstIterator it = addressees.constBegin();
+ it != addressees.constEnd(); ++it ) {
+ urls.append( KDEPIMPROTOCOL_CONTACT + ( *it ).uid() );
+ // there is some weirdness about realName(), hence fromUtf8
+ labels.append( TQString::fromUtf8( ( *it ).realName().latin1() ) );
+ }
+ probablyWeHaveUris = true;
+ } else if ( KURLDrag::canDecode( source ) ) {
+ TQMap<TQString,TQString> metadata;
+ if ( KURLDrag::decode( source, urls, metadata ) ) {
+ probablyWeHaveUris = true;
+ labels = TQStringList::split( ':', metadata["labels"], FALSE );
+ for ( TQStringList::Iterator it = labels.begin(); it != labels.end(); ++it ) {
+ *it = KURL::decode_string( (*it).latin1() );
+ }
+
+ }
+ } else if ( TQTextDrag::canDecode( source ) ) {
+ TQString text;
+ TQTextDrag::decode( source, text );
+ TQStringList lst = TQStringList::split( '\n', text, FALSE );
+ for ( TQStringList::ConstIterator it = lst.constBegin(); it != lst.constEnd(); ++it ) {
+ urls.append( *it );
+ labels.append( TQString::null );
+ }
+ probablyWeHaveUris = true;
+ }
+
+ KPopupMenu menu;
+ int items=0;
+ if ( probablyWeHaveUris ) {
+ menu.insertItem( i18n( "&Link here" ), DRAG_LINK, items++ );
+ // we need to check if we can reasonably expect to copy the objects
+ for ( KURL::List::ConstIterator it = urls.constBegin(); it != urls.constEnd(); ++it ) {
+ if ( !( weCanCopy = KProtocolInfo::supportsReading( *it ) ) ) {
+ break; // either we can copy them all, or no copying at all
+ }
+ }
+ if ( weCanCopy ) {
+ menu.insertItem( SmallIcon( "editcopy" ), i18n( "&Copy Here" ), DRAG_COPY, items++ );
+ }
+ } else {
+ menu.insertItem( SmallIcon( "editcopy" ), i18n( "&Copy Here" ), DRAG_COPY, items++ );
+ }
+
+ menu.insertSeparator();
+ items++;
+ menu.insertItem( SmallIcon( "cancel" ), i18n( "C&ancel" ), DRAG_CANCEL, items );
+ int action = menu.exec( TQCursor::pos(), 0 );
+
+ if ( action == DRAG_LINK ) {
+ TQStringList::ConstIterator jt = labels.constBegin();
+ for ( KURL::List::ConstIterator it = urls.constBegin();
+ it != urls.constEnd(); ++it ) {
+ TQString label = (*jt++);
+ if ( mAttachments->findItem( label ) ) {
+ label += '~' + randomString( 3 );
+ }
+ addUriAttachment( (*it).url(), TQString::null, label, true );
+ }
+ } else if ( action != DRAG_CANCEL ) {
+ if ( probablyWeHaveUris ) {
+ for ( KURL::List::ConstIterator it = urls.constBegin();
+ it != urls.constEnd(); ++it ) {
+ TQString label = (*it).fileName();
+ if ( label.isEmpty() ) {
+ label = (*it).prettyURL();
+ }
+ if ( mAttachments->findItem( label ) ) {
+ label += '~' + randomString( 3 );
+ }
+ addUriAttachment( (*it).url(), TQString::null, label, true );
+ }
+ } else { // we take anything
+ addDataAttachment( source->encodedData( source->format() ),
+ source->format(),
+ KMimeType::mimeType( source->format() )->name() );
}
}
}
@@ -293,95 +643,98 @@ void KOEditorAttachments::showAttachment( TQIconViewItem *item )
if ( !attitem || !attitem->attachment() ) return;
KCal::Attachment *att = attitem->attachment();
- if ( att->isUri() ) {
- emit openURL( att->uri() );
- } else {
- KTempFile f;
- if ( !f.file() )
- return;
- TQByteArray encoded;
- encoded.duplicate( att->data(), strlen(att->data()) );
- TQByteArray decoded;
- KCodecs::base64Decode( encoded, decoded );
- f.file()->writeBlock( decoded );
- f.file()->close();
- KRun::runURL( f.name(), att->mimeType(), true, false );
- }
+ KCal::AttachmentHandler::view( this, att );
+}
+
+void KOEditorAttachments::saveAttachment( TQIconViewItem *item )
+{
+ AttachmentListItem *attitem = static_cast<AttachmentListItem*>(item);
+ if ( !attitem || !attitem->attachment() ) return;
+
+ KCal::Attachment *att = attitem->attachment();
+ KCal::AttachmentHandler::saveAs( this, att );
}
void KOEditorAttachments::slotAdd()
{
- KURL uri = KPimURLRequesterDlg::getURL( TQString::null, i18n(
- "URL (e.g. a web page) or file to be attached (only "
- "the link will be attached, not the file itself):"), this,
- i18n("Add Attachment") );
- if ( !uri.isEmpty() ) {
- addAttachment( uri );
+ AttachmentListItem *item = new AttachmentListItem( 0, mAttachments );
+
+ AttachmentEditDialog *dlg = new AttachmentEditDialog( item, mAttachments )
+;
+ if ( dlg->exec() == KDialog::Rejected ) {
+ delete item;
}
+ delete dlg;
}
void KOEditorAttachments::slotAddData()
{
KURL uri = KFileDialog::getOpenFileName( TQString(), TQString(), this, i18n("Add Attachment") );
if ( !uri.isEmpty() ) {
- addAttachment( uri, TQString::null, false );
+ TQString label = uri.fileName();
+ if ( label.isEmpty() ) {
+ label = uri.prettyURL();
+ }
+ addUriAttachment( uri.url(), TQString::null, label, true );
}
}
void KOEditorAttachments::slotEdit()
{
- TQIconViewItem *item = mAttachments->currentItem();
- AttachmentListItem *attitem = static_cast<AttachmentListItem*>(item);
- if ( !attitem || !attitem->attachment() ) return;
-
- KCal::Attachment *att = attitem->attachment();
- if ( att->isUri() ) {
- KURL uri = KPimURLRequesterDlg::getURL( att->uri(), i18n(
- "URL (e.g. a web page) or file to be attached (only "
- "the link will be attached, not the file itself):"), this,
- i18n("Edit Attachment") );
-
- if ( !uri.isEmpty() )
- attitem->setUri( uri.url() );
- } else {
- KURL uri = KPimURLRequesterDlg::getURL( TQString::null, i18n(
- "File to be attached:"), this, i18n("Add Attachment") );
- if ( !uri.isEmpty() ) {
- TQString tmpFile;
- if ( KIO::NetAccess::download( uri, tmpFile, this ) ) {
- TQFile f( tmpFile );
- if ( !f.open( IO_ReadOnly ) )
- return;
- TQByteArray data = f.readAll();
- f.close();
- attitem->setData( KCodecs::base64Encode( data ) );
- attitem->setMimeType( KIO::NetAccess::mimetype( uri, this ) );
- TQString label = uri.fileName();
- if ( label.isEmpty() )
- label = uri.prettyURL();
- attitem->setLabel( label );
- KIO::NetAccess::removeTempFile( tmpFile );
+ for ( TQIconViewItem *item = mAttachments->firstItem(); item; item = item->nextItem() ) {
+ if ( item->isSelected() ) {
+ AttachmentListItem *attitem = static_cast<AttachmentListItem*>( item );
+ if ( !attitem || !attitem->attachment() ) {
+ return;
}
+
+ AttachmentEditDialog *dialog = new AttachmentEditDialog( attitem, mAttachments );
+ dialog->mInline->setEnabled( false );
+ dialog->setModal( false );
+ connect( dialog, TQT_SIGNAL(hidden()), dialog, TQT_SLOT(delayedDestruct()) );
+ dialog->show();
}
}
}
void KOEditorAttachments::slotRemove()
{
- TQValueList<TQIconViewItem*> selected;
- for ( TQIconViewItem *it = mAttachments->firstItem( ); it; it = it->nextItem( ) ) {
- if ( !it->isSelected() ) continue;
- selected << it;
- }
- if ( selected.isEmpty() || KMessageBox::warningContinueCancel(this,
- selected.count() == 1?i18n("This item will be permanently deleted."):
- i18n("The selected items will be permanently deleted."),
- i18n("KOrganizer Confirmation"),KStdGuiItem::del()) != KMessageBox::Continue )
- return;
+ TQValueList<TQIconViewItem*> selected;
+ TQStringList labels;
+ for ( TQIconViewItem *it = mAttachments->firstItem( ); it; it = it->nextItem( ) ) {
+ if ( !it->isSelected() ) continue;
+ selected << it;
+
+ AttachmentListItem *attitem = static_cast<AttachmentListItem*>(it);
+ KCal::Attachment *att = attitem->attachment();
+ labels << att->label();
+ }
- for ( TQValueList<TQIconViewItem*>::iterator it( selected.begin() ), end( selected.end() ); it != end ; ++it ) {
- delete *it;
+ if ( selected.isEmpty() ) {
+ return;
+ }
+
+ TQString labelsStr = labels.join( "<br>" );
+
+ if ( KMessageBox::questionYesNo(
+ this,
+ i18n( "<qt>Do you really want to remove these attachments?<p>%1</qt>" ).arg( labelsStr ),
+ i18n( "Remove Attachment?" ),
+ KStdGuiItem::yes(), KStdGuiItem::no(),
+ "calendarRemoveAttachments" ) != KMessageBox::Yes ) {
+ return;
+ }
+
+ for ( TQValueList<TQIconViewItem*>::iterator it( selected.begin() ), end( selected.end() );
+ it != end ; ++it ) {
+ if ( (*it)->nextItem() ) {
+ (*it)->nextItem()->setSelected( true );
+ } else if ( (*it)->prevItem() ) {
+ (*it)->prevItem()->setSelected( true );
}
+ delete *it;
+ }
+ mAttachments->slotUpdate();
}
void KOEditorAttachments::slotShow()
@@ -393,40 +746,98 @@ void KOEditorAttachments::slotShow()
}
}
+void KOEditorAttachments::slotSaveAs()
+{
+ for ( TQIconViewItem *it = mAttachments->firstItem(); it; it = it->nextItem() ) {
+ if ( !it->isSelected() )
+ continue;
+ saveAttachment( it );
+ }
+}
+
void KOEditorAttachments::setDefaults()
{
mAttachments->clear();
}
-void KOEditorAttachments::addAttachment( const KURL &uri,
- const TQString &mimeType, bool asUri )
+TQString KOEditorAttachments::randomString(int length) const
{
- AttachmentListItem *item = new AttachmentListItem( 0, mAttachments );
- if ( asUri ) {
- item->setUri( uri.url() );
- if ( !mimeType.isEmpty() ) item->setMimeType( mimeType );
+ if (length <=0 ) return TQString();
+
+ TQString str; str.setLength( length );
+ int i = 0;
+ while (length--)
+ {
+ int r=random() % 62;
+ r+=48;
+ if (r>57) r+=7;
+ if (r>90) r+=6;
+ str[i++] = char(r);
+ // so what if I work backwards?
+ }
+ return str;
+}
+
+void KOEditorAttachments::addUriAttachment( const TQString &uri,
+ const TQString &mimeType,
+ const TQString &label,
+ bool inLine )
+{
+ if ( !inLine ) {
+ AttachmentListItem *item = new AttachmentListItem( 0, mAttachments );
+ item->setUri( uri );
+ item->setLabel( label );
+ if ( mimeType.isEmpty() ) {
+ if ( uri.startsWith( KDEPIMPROTOCOL_CONTACT ) ) {
+ item->setMimeType( "text/directory" );
+ } else if ( uri.startsWith( KDEPIMPROTOCOL_EMAIL ) ) {
+ item->setMimeType( "message/rfc822" );
+ } else if ( uri.startsWith( KDEPIMPROTOCOL_INCIDENCE ) ) {
+ item->setMimeType( "text/calendar" );
+ } else if ( uri.startsWith( KDEPIMPROTOCOL_NEWSARTICLE ) ) {
+ item->setMimeType( "message/news" );
+ } else {
+ item->setMimeType( KMimeType::findByURL( uri )->name() );
+ }
+ }
} else {
TQString tmpFile;
if ( KIO::NetAccess::download( uri, tmpFile, this ) ) {
TQFile f( tmpFile );
- if ( !f.open( IO_ReadOnly ) )
+ if ( !f.open( IO_ReadOnly ) ) {
return;
- TQByteArray data = f.readAll();
+ }
+ const TQByteArray data = f.readAll();
f.close();
- item->setData( KCodecs::base64Encode( data ) );
- if ( !mimeType.isEmpty() )
- item->setMimeType( mimeType );
- else
- item->setMimeType( KIO::NetAccess::mimetype( uri, this ) );
- TQString label = uri.fileName();
- if ( label.isEmpty() )
- label = uri.prettyURL();
- item->setLabel( label );
- KIO::NetAccess::removeTempFile( tmpFile );
+ addDataAttachment( data, mimeType, label );
}
+ KIO::NetAccess::removeTempFile( tmpFile );
}
}
+void KOEditorAttachments::addDataAttachment( const TQByteArray &data,
+ const TQString &mimeType,
+ const TQString &label )
+{
+ AttachmentListItem *item = new AttachmentListItem( 0, mAttachments );
+
+ TQString nlabel = label;
+ if ( mimeType == "message/rfc822" ) {
+ // mail message. try to set the label from the mail Subject:
+ KMime::Message msg;
+ msg.setContent( data.data() );
+ msg.parse();
+ nlabel = msg.subject()->asUnicodeString();
+ }
+
+ item->setData( data );
+ item->setLabel( nlabel );
+ if ( mimeType.isEmpty() ) {
+ item->setMimeType( KMimeType::findByContent( data )->name() );
+ } else {
+ item->setMimeType( mimeType );
+ }
+}
void KOEditorAttachments::addAttachment( KCal::Attachment *attachment )
{
@@ -463,7 +874,7 @@ void KOEditorAttachments::writeIncidence( KCal::Incidence *i )
void KOEditorAttachments::slotCopy()
{
- TQApplication::clipboard()->setData( mAttachments->dragObject(), QClipboard::Clipboard );
+ TQApplication::clipboard()->setData( mAttachments->mimeData(), QClipboard::Clipboard );
}
void KOEditorAttachments::slotCut()
@@ -492,9 +903,21 @@ void KOEditorAttachments::selectionChanged()
void KOEditorAttachments::contextMenu(TQIconViewItem * item, const TQPoint & pos)
{
const bool enable = item != 0;
+
+ int numSelected = 0;
+ for ( TQIconViewItem *item = mAttachments->firstItem(); item; item = item->nextItem() ) {
+ if ( item->isSelected() ) {
+ numSelected++;
+ }
+ }
+
mOpenAction->setEnabled( enable );
- mCopyAction->setEnabled( enable );
- mCutAction->setEnabled( enable );
+ //TODO: support saving multiple attachments into a directory
+ mSaveAsAction->setEnabled( enable && numSelected == 1 );
+ mCopyAction->setEnabled( enable && numSelected == 1 );
+ mCutAction->setEnabled( enable && numSelected == 1 );
+ mDeleteAction->setEnabled( enable );
+ mEditAction->setEnabled( enable );
mContextMenu->exec( pos );
}
diff --git a/korganizer/koeditorattachments.h b/korganizer/koeditorattachments.h
index 09b2c48e..dfcdb2b5 100644
--- a/korganizer/koeditorattachments.h
+++ b/korganizer/koeditorattachments.h
@@ -26,19 +26,56 @@
#define KOEDITORATTACHMENTS_H
#include <tqwidget.h>
+#include <tqmap.h>
+#include <kdialogbase.h>
+#include <kmimetype.h>
#include <kurl.h>
+#include <kiconview.h>
+
+#include <set>
+
+class AttachmentListItem;
+class AttachmentIconView;
namespace KCal {
class Incidence;
class Attachment;
}
+class TQCheckBox;
class TQIconViewItem;
-class AttachmentIconView;
+class TQLabel;
class TQMimeSource;
class TQPushButton;
class TQPopupMenu;
+
class KAction;
+class KLineEdit;
+class KURLRequester;
+class KTempDir;
+
+class AttachmentEditDialog : public KDialogBase
+{
+ Q_OBJECT
+ public:
+ AttachmentEditDialog( AttachmentListItem *item, TQWidget *parent=0 );
+
+ void accept();
+
+ protected slots:
+ void urlSelected( const TQString &url );
+ void urlChanged( const TQString & url );
+ virtual void slotApply();
+
+ private:
+ friend class KOEditorAttachments;
+ KMimeType::Ptr mMimeType;
+ AttachmentListItem *mItem;
+ TQLabel *mTypeLabel, *mIcon;
+ TQCheckBox *mInline;
+ KLineEdit *mLabelEdit;
+ KURLRequester *mURLRequester;
+};
class KOEditorAttachments : public QWidget
{
@@ -48,9 +85,14 @@ class KOEditorAttachments : public QWidget
const char *name = 0 );
~KOEditorAttachments();
- void addAttachment( const KURL &uri,
- const TQString &mimeType = TQString::null, bool asUri = true );
+ void addUriAttachment( const TQString &uri,
+ const TQString &mimeType = TQString(),
+ const TQString &label = TQString(),
+ bool inLine = false );
void addAttachment( KCal::Attachment *attachment );
+ void addDataAttachment( const TQByteArray &data,
+ const TQString &mimeType = TQString(),
+ const TQString &label = TQString() );
/** Set widgets to default values */
void setDefaults();
@@ -63,29 +105,75 @@ class KOEditorAttachments : public QWidget
protected slots:
void showAttachment( TQIconViewItem *item );
+ void saveAttachment( TQIconViewItem *item );
void slotAdd();
void slotAddData();
void slotEdit();
void slotRemove();
void slotShow();
+ void slotSaveAs();
void dragEnterEvent( TQDragEnterEvent *event );
+ void dragMoveEvent( TQDragMoveEvent *event );
void dropEvent( TQDropEvent *event );
void slotCopy();
void slotCut();
void slotPaste();
void selectionChanged();
void contextMenu( TQIconViewItem* item, const TQPoint &pos );
+
signals:
void openURL( const KURL &url );
+ protected:
+ enum {
+ DRAG_COPY = 0,
+ DRAG_LINK = 1,
+ DRAG_CANCEL = 2
+ };
+
private:
friend class AttachmentIconView;
void handlePasteOrDrop( TQMimeSource* source );
-
+ TQString randomString( int length ) const;
AttachmentIconView *mAttachments;
TQPushButton *mRemoveBtn;
TQPopupMenu *mContextMenu, *mAddMenu;
- KAction *mOpenAction, *mCopyAction, *mCutAction;
+ KAction *mOpenAction;
+ KAction *mSaveAsAction;
+ KAction *mCopyAction;
+ KAction *mCutAction;
+ KAction *mDeleteAction;
+ KAction *mEditAction;
+};
+
+
+class AttachmentIconView : public KIconView
+{
+ Q_OBJECT
+
+ friend class KOEditorAttachments;
+ public:
+ AttachmentIconView( KOEditorAttachments* parent=0 );
+ KURL tempFileForAttachment( KCal::Attachment *attachment );
+ TQDragObject *mimeData();
+ ~AttachmentIconView();
+
+ protected:
+ TQDragObject * dragObject();
+
+ void dragMoveEvent( TQDragMoveEvent *event );
+ void contentsDragMoveEvent( TQDragMoveEvent *event );
+ void contentsDragEnterEvent( TQDragEnterEvent *event );
+ void dragEnterEvent( TQDragEnterEvent *event );
+
+ protected slots:
+
+ void handleDrop( TQDropEvent *event, const TQValueList<TQIconDragItem> & list );
+
+ private:
+ std::set<KTempDir*> mTempDirs;
+ TQMap<KCal::Attachment *, KURL> mTempFiles;
+ KOEditorAttachments* mParent;
};
#endif
diff --git a/korganizer/koeditordetails.cpp b/korganizer/koeditordetails.cpp
index 0b8c6159..a882363d 100644
--- a/korganizer/koeditordetails.cpp
+++ b/korganizer/koeditordetails.cpp
@@ -72,7 +72,8 @@
template <>
CustomListViewItem<KCal::Attendee *>::~CustomListViewItem()
{
- delete mData;
+ // do not delete mData here
+// delete mData;
}
template <>
@@ -152,18 +153,15 @@ void KOAttendeeListView::dropEvent( TQDropEvent *e )
{
#ifndef KORG_NODND
TQString text;
- TQString vcards;
#ifndef KORG_NOKABC
- if ( KVCardDrag::decode( e, vcards ) ) {
- KABC::VCardConverter converter;
-
- KABC::Addressee::List list = converter.parseVCards( vcards );
+ KABC::Addressee::List list;
+ if ( KVCardDrag::decode( e, list ) ) {
KABC::Addressee::List::Iterator it;
for ( it = list.begin(); it != list.end(); ++it ) {
TQString em( (*it).fullEmail() );
- if (em.isEmpty()) {
- em=(*it).realName();
+ if ( em.isEmpty() ) {
+ em = (*it).realName();
}
addAttendee( em );
}
@@ -240,13 +238,22 @@ void KOEditorDetails::removeAttendee()
static_cast<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 );
+ AttendeeListItem *nextSelectedItem = static_cast<AttendeeListItem*>( aItem->nextSibling() );
+ if( mListView->childCount() == 1 )
+ nextSelectedItem = 0;
+ if( mListView->childCount() > 1 && aItem == mListView->lastItem() )
+ nextSelectedItem = static_cast<AttendeeListItem*>( mListView->firstChild() );
+ Attendee *attendee = aItem->data();
+ Attendee *delA = new Attendee( attendee->name(), attendee->email(),
+ attendee->RSVP(), attendee->status(),
+ attendee->role(), attendee->uid() );
+ mdelAttendees.append( delA );
delete aItem;
+ if( nextSelectedItem ) {
+ mListView->setSelected( nextSelectedItem, true );
+ }
updateAttendeeInput();
emit updateAttendeeSummary( mListView->childCount() );
}
@@ -257,12 +264,25 @@ void KOEditorDetails::insertAttendee( Attendee *a, bool goodEmailAddress )
Q_UNUSED( goodEmailAddress );
// lastItem() is O(n), but for n very small that should be fine
- AttendeeListItem *item = new AttendeeListItem( a, mListView,
- static_cast<KListViewItem*>( mListView->lastItem() ) );
+ AttendeeListItem *item = new AttendeeListItem(
+ a, mListView, static_cast<KListViewItem*>( mListView->lastItem() ) );
mListView->setSelected( item, true );
emit updateAttendeeSummary( mListView->childCount() );
}
+void KOEditorDetails::removeAttendee( Attendee *attendee )
+{
+ TQListViewItem *item;
+ for ( item = mListView->firstChild(); item; item = item->nextSibling() ) {
+ AttendeeListItem *anItem = static_cast<AttendeeListItem *>( item );
+ Attendee *att = anItem->data();
+ if ( att == attendee ) {
+ delete anItem;
+ break;
+ }
+ }
+}
+
void KOEditorDetails::setDefaults()
{
mRsvpButton->setChecked( true );
@@ -350,9 +370,34 @@ void KOEditorDetails::updateCurrentItem()
item->updateItem();
}
-void KOEditorDetails::slotInsertAttendee(Attendee * a)
+void KOEditorDetails::slotInsertAttendee( Attendee *a )
{
insertAttendee( a );
+ mnewAttendees.append( a );
+}
+
+void KOEditorDetails::setSelected( int index )
+{
+ int count = 0;
+ for ( TQListViewItemIterator it( mListView ); it.current(); ++it ) {
+ if ( count == index ) {
+ mListView->setSelected( *it, true );
+ return;
+ }
+ count++;
+ }
+}
+
+int KOEditorDetails::selectedIndex()
+{
+ int index = 0;
+ for ( TQListViewItemIterator it( mListView ); it.current(); ++it ) {
+ if ( mListView->isSelected( *it ) ) {
+ break;
+ }
+ index++;
+ }
+ return index;
}
void KOEditorDetails::changeStatusForMe(Attendee::PartStat status)
@@ -369,4 +414,16 @@ void KOEditorDetails::changeStatusForMe(Attendee::PartStat status)
}
}
+TQListViewItem* KOEditorDetails::hasExampleAttendee() const
+{
+ for ( TQListViewItemIterator it( mListView ); it.current(); ++it ) {
+ AttendeeListItem *item = static_cast<AttendeeListItem*>( it.current() );
+ Attendee *attendee = item->data();
+ Q_ASSERT( attendee );
+ if ( isExampleAttendee( attendee ) )
+ return item;
+ }
+ return 0;
+}
+
#include "koeditordetails.moc"
diff --git a/korganizer/koeditordetails.h b/korganizer/koeditordetails.h
index 92a27164..890841f6 100644
--- a/korganizer/koeditordetails.h
+++ b/korganizer/koeditordetails.h
@@ -95,16 +95,21 @@ class KOEditorDetails : public KOAttendeeEditor
/** Returns whether at least one attendee was added */
bool hasAttendees();
- void insertAttendee( Attendee*, bool goodEmailAddress = true );
+ void insertAttendee( Attendee *a, bool goodEmailAddress = true );
+ void removeAttendee( Attendee *a );
protected slots:
void removeAttendee();
void slotInsertAttendee( Attendee *a );
protected:
+ void setSelected ( int index );
+ int selectedIndex();
void changeStatusForMe( Attendee::PartStat status );
KCal::Attendee* currentAttendee() const;
+ /* reimpl */
+ TQListViewItem* hasExampleAttendee() const;
void updateCurrentItem();
private:
diff --git a/korganizer/koeditorfreebusy.cpp b/korganizer/koeditorfreebusy.cpp
index 19691e80..c56ff033 100644
--- a/korganizer/koeditorfreebusy.cpp
+++ b/korganizer/koeditorfreebusy.cpp
@@ -130,7 +130,8 @@ class FreeBusyItem : public KDGanttViewTaskItem
void FreeBusyItem::updateItem()
{
- setListViewText( 0, mAttendee->fullName() );
+ TQString text = mAttendee->name() + " <" + mAttendee->email() + '>';
+ setListViewText( 0, text );
switch ( mAttendee->status() ) {
case Attendee::Accepted:
setPixmap( 0, KOGlobals::self()->smallIcon( "ok" ) );
@@ -166,17 +167,34 @@ void FreeBusyItem::setFreeBusyPeriods( FreeBusy* fb )
TQValueList<KCal::Period> busyPeriods = fb->busyPeriods();
for( TQValueList<KCal::Period>::Iterator it = busyPeriods.begin();
it != busyPeriods.end(); ++it ) {
- KDGanttViewTaskItem* newSubItem = new KDGanttViewTaskItem( this );
- newSubItem->setStartTime( (*it).start() );
- newSubItem->setEndTime( (*it).end() );
+ Period per = *it;
+
+ KDGanttViewTaskItem *newSubItem = new KDGanttViewTaskItem( this );
+ newSubItem->setStartTime( per.start() );
+ newSubItem->setEndTime( per.end() );
newSubItem->setColors( Qt::red, Qt::red, Qt::red );
- TQString toolTip;
- if ( !(*it).summary().isEmpty() )
- toolTip += "<b>" + (*it).summary() + "</b><br/>";
- if ( !(*it).location().isEmpty() )
- toolTip += i18n( "Location: %1" ).arg( (*it).location() );
- if ( !toolTip.isEmpty() )
- newSubItem->setTooltipText( toolTip );
+
+ TQString toolTip = "<qt>";
+ toolTip += "<b>" + i18n( "Freebusy Period" ) + "</b>";
+ toolTip += "<br>----------------------<br>";
+ if ( !per.summary().isEmpty() ) {
+ toolTip += "<i>" + i18n( "Summary:" ) + "</i>" + "&nbsp;";
+ toolTip += per.summary();
+ toolTip += "<br>";
+ }
+ if ( !per.location().isEmpty() ) {
+ toolTip += "<i>" + i18n( "Location:" ) + "</i>" + "&nbsp;";
+ toolTip += per.location();
+ toolTip += "<br>";
+ }
+ toolTip += "<i>" + i18n( "Start:" ) + "</i>" + "&nbsp;";
+ toolTip += KGlobal::locale()->formatDateTime( per.start() );
+ toolTip += "<br>";
+ toolTip += "<i>" + i18n( "End:" ) + "</i>" + "&nbsp;";
+ toolTip += KGlobal::locale()->formatDateTime( per.end() );
+ toolTip += "<br>";
+ toolTip += "</qt>";
+ newSubItem->setTooltipText( toolTip );
}
setFreeBusy( fb );
setShowNoInformation( false );
@@ -529,12 +547,18 @@ void KOEditorFreeBusy::slotPickDate()
i18n( "The meeting already has suitable start/end times." ), TQString::null,
"MeetingTimeOKFreeBusy" );
} else {
- emit dateTimesChanged( start, end );
- slotUpdateGanttView( start, end );
- KMessageBox::information( this,
- i18n( "The meeting has been moved to\nStart: %1\nEnd: %2." )
- .arg( start.toString() ).arg( end.toString() ), TQString::null,
- "MeetingMovedFreeBusy" );
+ if ( KMessageBox::questionYesNo(
+ this,
+ i18n( "<qt>The next available time slot for the meeting is:<br>"
+ "Start: %1<br>End: %2<br>"
+ "Would you like to move the meeting to this time slot?</qt>" ).
+ arg( start.toString(), end.toString() ),
+ TQString::null,
+ KStdGuiItem::yes(), KStdGuiItem::no(),
+ "MeetingMovedFreeBusy" ) == KMessageBox::Yes ) {
+ emit dateTimesChanged( start, end );
+ slotUpdateGanttView( start, end );
+ }
}
} else
KMessageBox::sorry( this, i18n( "No suitable date found." ) );
@@ -664,6 +688,7 @@ void KOEditorFreeBusy::updateStatusSummary()
case Attendee::Delegated:
case Attendee::Completed:
case Attendee::InProcess:
+ case Attendee::None:
/* just to shut up the compiler */
break;
}
@@ -803,6 +828,12 @@ void KOEditorFreeBusy::removeAttendee()
if ( !item )
return;
+ FreeBusyItem *nextSelectedItem = static_cast<FreeBusyItem*>( item->nextSibling() );
+ if( mGanttView->childCount() == 1 )
+ nextSelectedItem = 0;
+ if( mGanttView->childCount() > 1 && item == mGanttView->lastItem() )
+ nextSelectedItem = static_cast<FreeBusyItem*>( mGanttView->firstChild() );
+
Attendee *delA = new Attendee( item->attendee()->name(), item->attendee()->email(),
item->attendee()->RSVP(), item->attendee()->status(),
item->attendee()->role(), item->attendee()->uid() );
@@ -810,6 +841,8 @@ void KOEditorFreeBusy::removeAttendee()
delete item;
updateStatusSummary();
+ if( nextSelectedItem )
+ mGanttView->setSelected( nextSelectedItem, true );
updateAttendeeInput();
emit updateAttendeeSummary( mGanttView->childCount() );
}
@@ -823,6 +856,32 @@ void KOEditorFreeBusy::clearSelection() const
item->repaint();
}
+void KOEditorFreeBusy::setSelected( int index )
+{
+ int count = 0;
+ for( KDGanttViewItem *it = mGanttView->firstChild(); it; it = it->nextSibling() ) {
+ FreeBusyItem *item = static_cast<FreeBusyItem*>( it );
+ if ( count == index ) {
+ mGanttView->setSelected( item, true );
+ return;
+ }
+ count++;
+ }
+}
+
+int KOEditorFreeBusy::selectedIndex()
+{
+ int index = 0;
+ for ( KDGanttViewItem *it = mGanttView->firstChild(); it; it = it->nextSibling() ) {
+ FreeBusyItem *item = static_cast<FreeBusyItem*>( it );
+ if ( item->isSelected() ) {
+ break;
+ }
+ index++;
+ }
+ return index;
+}
+
void KOEditorFreeBusy::changeStatusForMe(KCal::Attendee::PartStat status)
{
const TQStringList myEmails = KOPrefs::instance()->allEmails();
@@ -911,6 +970,7 @@ void KOEditorFreeBusy::slotOrganizerChanged(const TQString & newOrganizer)
if (!newOrganizerAttendee) {
Attendee *a = new Attendee( name, email, true );
insertAttendee( a, false );
+ mnewAttendees.append( a );
updateAttendee();
}
}
@@ -928,4 +988,16 @@ bool KOEditorFreeBusy::eventFilter( TQObject *watched, TQEvent *event )
}
}
+TQListViewItem* KOEditorFreeBusy::hasExampleAttendee() const
+{
+ for ( FreeBusyItem *item = static_cast<FreeBusyItem *>( mGanttView->firstChild() ); item;
+ item = static_cast<FreeBusyItem*>( item->nextSibling() ) ) {
+ Attendee *attendee = item->attendee();
+ Q_ASSERT( attendee );
+ if ( isExampleAttendee( attendee ) )
+ return item;
+ }
+ return 0;
+}
+
#include "koeditorfreebusy.moc"
diff --git a/korganizer/koeditorfreebusy.h b/korganizer/koeditorfreebusy.h
index 4e561cfa..72ce6e7d 100644
--- a/korganizer/koeditorfreebusy.h
+++ b/korganizer/koeditorfreebusy.h
@@ -93,8 +93,12 @@ class KOEditorFreeBusy : public KOAttendeeEditor
protected:
void timerEvent( TQTimerEvent* );
KCal::Attendee* currentAttendee() const;
+ /* reimpl */
+ TQListViewItem* hasExampleAttendee() const;
void updateCurrentItem();
void clearSelection() const;
+ void setSelected ( int index );
+ int selectedIndex();
void changeStatusForMe( KCal::Attendee::PartStat status );
virtual bool eventFilter( TQObject *watched, TQEvent *event );
diff --git a/korganizer/koeditorgeneral.cpp b/korganizer/koeditorgeneral.cpp
index 816806e3..e1d8db24 100644
--- a/korganizer/koeditorgeneral.cpp
+++ b/korganizer/koeditorgeneral.cpp
@@ -30,7 +30,6 @@
#include <tqhbox.h>
#include <tqbuttongroup.h>
#include <tqvgroupbox.h>
-#include <tqwidgetstack.h>
#include <tqdatetime.h>
#include <tqlineedit.h>
#include <tqlabel.h>
@@ -54,6 +53,7 @@
#include <libkcal/todo.h>
#include <libkcal/event.h>
+#include <libkcal/incidenceformatter.h>
#include <libkcal/resourcecached.h>
#include <libkdepim/kdateedit.h>
@@ -68,9 +68,10 @@
#include "koeditorgeneral.moc"
#include "kohelper.h"
-KOEditorGeneral::KOEditorGeneral(TQObject* parent, const char* name) :
+KOEditorGeneral::KOEditorGeneral( TQObject *parent, const char* name) :
TQObject( parent, name ), mAttachments(0)
{
+ mType = "Event";
ResourceCached::setEditorWindowOpen(true);
mAlarmList.setAutoDelete( true );
}
@@ -103,11 +104,6 @@ void KOEditorGeneral::initHeader( TQWidget *parent,TQBoxLayout *topLayout)
headerLayout->setSpacing( topLayout->spacing() );
topLayout->addLayout( headerLayout );
-#if 0
- mOwnerLabel = new TQLabel(i18n("Owner:"),parent);
- headerLayout->addMultiCellWidget(mOwnerLabel,0,0,0,1);
-#endif
-
TQString whatsThis = i18n("Sets the Title of this event or to-do.");
TQLabel *summaryLabel = new TQLabel( i18n("T&itle:"), parent );
TQWhatsThis::add( summaryLabel, whatsThis );
@@ -198,52 +194,63 @@ void KOEditorGeneral::initDescription(TQWidget *parent,TQBoxLayout *topLayout)
topLayout->addWidget(mDescriptionEdit, 4);
}
-void KOEditorGeneral::initAlarm(TQWidget *parent,TQBoxLayout *topLayout)
+void KOEditorGeneral::initAlarm( TQWidget *parent, TQBoxLayout *topLayout )
{
- TQBoxLayout *alarmLayout = new TQHBoxLayout(topLayout);
-
- mAlarmBell = new TQLabel(parent);
- mAlarmBell->setPixmap(KOGlobals::self()->smallIcon("bell"));
- alarmLayout->addWidget( mAlarmBell );
-
-
- mAlarmStack = new TQWidgetStack( parent );
- alarmLayout->addWidget( mAlarmStack );
-
- mAlarmInfoLabel = new TQLabel( i18n("No reminders configured"), mAlarmStack );
- mAlarmStack->addWidget( mAlarmInfoLabel, AdvancedAlarmLabel );
-
- TQHBox *simpleAlarmBox = new TQHBox( mAlarmStack );
- mAlarmStack->addWidget( simpleAlarmBox, SimpleAlarmPage );
-
- mAlarmButton = new TQCheckBox(i18n("&Reminder:"), simpleAlarmBox );
- TQWhatsThis::add( mAlarmButton,
- i18n("Activates a reminder for this event or to-do.") );
-
- TQString whatsThis = i18n("Sets how long before the event occurs "
- "the reminder will be triggered.");
- mAlarmTimeEdit = new TQSpinBox( 0, 99999, 1, simpleAlarmBox, "alarmTimeEdit" );
+ TQBoxLayout *alarmLayout = new TQHBoxLayout( topLayout );
+
+ mAlarmButton = new TQCheckBox( parent );
+ TQWhatsThis::add( mAlarmButton, i18n( "Enable reminders for this event or to-do." ) );
+ TQToolTip::add( mAlarmButton, i18n( "Enable reminders" ) );
+ alarmLayout->addWidget( mAlarmButton );
+
+ mAlarmAdvancedButton = new TQPushButton( parent );
+ mAlarmAdvancedButton->setIconSet( KOGlobals::self()->smallIconSet( "bell", 16 ) );
+ TQWhatsThis::add( mAlarmAdvancedButton,
+ i18n( "Push this button to create an advanced set of reminders "
+ "for this event or to-do." ) );
+ TQToolTip::add( mAlarmAdvancedButton, i18n( "Set an advanced reminder" ) );
+ connect( mAlarmAdvancedButton, TQT_SIGNAL(clicked()), TQT_SLOT(editAlarms()) );
+ alarmLayout->addWidget( mAlarmAdvancedButton );
+
+ mSimpleAlarmBox = new TQHBox( parent );
+ alarmLayout->addWidget( mSimpleAlarmBox );
+
+ TQString whatsThis, toolTip;
+ if ( mType == "Event" ) {
+ whatsThis = i18n( "Set the time before the event starts when the reminder will be triggered." );
+ toolTip = i18n( "Set the start time trigger offset" );
+ } else {
+ whatsThis = i18n( "Set the time before the to-do is due when the reminder will be triggered." );
+ toolTip = i18n( "Set the due time trigger offset" );
+ }
+ mAlarmTimeEdit = new TQSpinBox( 0, 99999, 1, mSimpleAlarmBox, "alarmTimeEdit" );
mAlarmTimeEdit->setValue( 0 );
TQWhatsThis::add( mAlarmTimeEdit, whatsThis );
+ TQToolTip::add( mAlarmTimeEdit, toolTip );
- mAlarmIncrCombo = new TQComboBox( false, simpleAlarmBox );
- TQWhatsThis::add( mAlarmIncrCombo, whatsThis );
+ mAlarmIncrCombo = new TQComboBox( false, mSimpleAlarmBox );
mAlarmIncrCombo->insertItem( i18n("minute(s)") );
mAlarmIncrCombo->insertItem( i18n("hour(s)") );
mAlarmIncrCombo->insertItem( i18n("day(s)") );
-// mAlarmIncrCombo->setMinimumHeight(20);
- connect(mAlarmButton, TQT_SIGNAL(toggled(bool)), mAlarmTimeEdit, TQT_SLOT(setEnabled(bool)));
- connect(mAlarmButton, TQT_SIGNAL(toggled(bool)), mAlarmIncrCombo, TQT_SLOT(setEnabled(bool)));
- mAlarmTimeEdit->setEnabled( false );
- mAlarmIncrCombo->setEnabled( false );
+ TQWhatsThis::add( mAlarmIncrCombo, whatsThis );
+ TQToolTip::add( mAlarmIncrCombo, toolTip );
- mAlarmEditButton = new TQPushButton( i18n("Advanced"), parent );
- mAlarmEditButton->setEnabled( false );
- alarmLayout->addWidget( mAlarmEditButton );
- connect( mAlarmButton, TQT_SIGNAL(toggled(bool)), mAlarmEditButton, TQT_SLOT(setEnabled( bool)));
- connect( mAlarmEditButton, TQT_SIGNAL( clicked() ),
- TQT_SLOT( editAlarms() ) );
+ mAlarmInfoLabel = new TQLabel( parent );
+ if ( mType == "Event" ) {
+ mAlarmInfoLabel->setText( i18n( "before the start" ) );
+ } else {
+ mAlarmInfoLabel->setText( i18n( "before the due time" ) );
+ }
+ alarmLayout->addWidget( mAlarmInfoLabel );
+ mAlarmAdvancedButton->setEnabled( false );
+ mAlarmTimeEdit->setEnabled( false );
+ mAlarmIncrCombo->setEnabled( false );
+ mAlarmInfoLabel->setEnabled( false );
+ connect( mAlarmButton, TQT_SIGNAL(toggled(bool)), mAlarmAdvancedButton, TQT_SLOT(setEnabled(bool)) );
+ connect( mAlarmButton, TQT_SIGNAL(toggled(bool)), mAlarmTimeEdit, TQT_SLOT(setEnabled(bool)) );
+ connect( mAlarmButton, TQT_SIGNAL(toggled(bool)), mAlarmIncrCombo, TQT_SLOT(setEnabled(bool)) );
+ connect( mAlarmButton, TQT_SIGNAL(toggled(bool)), mAlarmInfoLabel, TQT_SLOT(setEnabled(bool)) );
}
void KOEditorGeneral::initAttachments(TQWidget *parent,TQBoxLayout *topLayout)
@@ -254,6 +261,12 @@ void KOEditorGeneral::initAttachments(TQWidget *parent,TQBoxLayout *topLayout)
topLayout->addWidget( mAttachments, 1 );
}
+void KOEditorGeneral::setType( const TQCString &type )
+{
+ // must be "Event", "Todo", "Journal", etc.
+ mType = type;
+}
+
void KOEditorGeneral::addAttachments( const TQStringList &attachments,
const TQStringList &mimeTypes,
bool inlineAttachments )
@@ -261,10 +274,13 @@ void KOEditorGeneral::addAttachments( const TQStringList &attachments,
TQStringList::ConstIterator it;
uint i = 0;
for ( it = attachments.begin(); it != attachments.end(); ++it, ++i ) {
- TQString mimeType;
- if ( mimeTypes.count() > i )
- mimeType = mimeTypes[ i ];
- mAttachments->addAttachment( *it, mimeType, !inlineAttachments );
+ if ( !(*it).isEmpty() ) {
+ TQString mimeType;
+ if ( mimeTypes.count() > i ) {
+ mimeType = mimeTypes[ i ];
+ }
+ mAttachments->addUriAttachment( *it, mimeType, TQString(), inlineAttachments );
+ }
}
}
@@ -286,31 +302,48 @@ void KOEditorGeneral::selectCategories()
void KOEditorGeneral::editAlarms()
{
- if ( mAlarmStack->id( mAlarmStack->visibleWidget() ) == SimpleAlarmPage ) {
+ if ( mAlarmIsSimple ) {
mAlarmList.clear();
- Alarm *al = alarmFromSimplePage();
+ Alarm *al = alarmFromSimplePage( 0 );
if ( al ) {
mAlarmList.append( al );
}
}
- KOEditorAlarms *dlg = new KOEditorAlarms( &mAlarmList, mAlarmEditButton );
+ KOEditorAlarms *dlg = new KOEditorAlarms( mType, &mAlarmList, mAlarmAdvancedButton );
if ( dlg->exec() != KDialogBase::Cancel ) {
- updateAlarmWidgets();
+ if ( mType == "Event" ) {
+ Event *e = new Event;
+ Alarm::List::ConstIterator it;
+ for( it = mAlarmList.begin(); it != mAlarmList.end(); ++it ) {
+ Alarm *a = (*it)->clone();
+ a->setParent( e );
+ e->addAlarm( a );
+ }
+ updateAlarmWidgets( e );
+ delete e;
+ } else {
+ Todo *t = new Todo;
+ Alarm::List::ConstIterator it;
+ for( it = mAlarmList.begin(); it != mAlarmList.end(); ++it ) {
+ Alarm *a = (*it)->clone();
+ a->setParent( t );
+ t->addAlarm( a );
+ }
+ updateAlarmWidgets( t );
+ delete t;
+ }
}
}
-
void KOEditorGeneral::enableAlarm( bool enable )
{
- mAlarmStack->setEnabled( enable );
- mAlarmEditButton->setEnabled( enable );
+ mAlarmAdvancedButton->setEnabled( enable );
}
-
void KOEditorGeneral::toggleAlarm( bool on )
{
- mAlarmButton->setChecked( on );
+ mAlarmButton->setChecked( on );
}
void KOEditorGeneral::setCategories( const TQStringList &categories )
@@ -321,65 +354,104 @@ void KOEditorGeneral::setCategories( const TQStringList &categories )
void KOEditorGeneral::setDefaults(bool /*allDay*/)
{
-#if 0
- mOwnerLabel->setText(i18n("Owner: ") + KOPrefs::instance()->fullName());
-#endif
-
mAlarmList.clear();
updateDefaultAlarmTime();
- updateAlarmWidgets();
+ updateAlarmWidgets( 0 );
- mSecrecyCombo->setCurrentItem(Incidence::SecrecyPublic);
+ mSecrecyCombo->setCurrentItem( Incidence::SecrecyPublic );
mAttachments->setDefaults();
}
void KOEditorGeneral::updateDefaultAlarmTime()
{
- // FIXME: Implement a KPrefsComboItem to solve this in a clean way.
-// FIXME: Use an int value for minutes instead of 5 hardcoded values
- int alarmTime;
- int a[] = { 1,5,10,15,30 };
- int index = KOPrefs::instance()->mAlarmTime;
- if (index < 0 || index > 4) {
- alarmTime = 0;
- } else {
- alarmTime = a[index];
+ int reminderTime = KOPrefs::instance()->mReminderTime;
+ int index = KOPrefs::instance()->mReminderTimeUnits;
+ if ( index < 0 || index > 2 ) {
+ index = 0;
}
- mAlarmTimeEdit->setValue(alarmTime);
+ mAlarmTimeEdit->setValue( reminderTime );
+ mAlarmIncrCombo->setCurrentItem( index );
}
-void KOEditorGeneral::updateAlarmWidgets()
+bool KOEditorGeneral::isSimpleAlarm( Alarm *alarm ) const
{
- if ( mAlarmList.isEmpty() ) {
- mAlarmStack->raiseWidget( SimpleAlarmPage );
- if (KOPrefs::instance()->mAlarmsEnabledByDefault == true) {
- mAlarmButton->setChecked( true );
+ // Check if its the trivial type of alarm, which can be
+ // configured with a simply spin box...
+
+ bool simple = false;
+ if ( alarm->type() == Alarm::Display && alarm->text().isEmpty() &&
+ alarm->repeatCount() == 0 && !alarm->hasTime() ) {
+ if ( mType == "Event" &&
+ alarm->hasStartOffset() && alarm->startOffset().asSeconds() <= 0 ) {
+ simple = true;
}
- else {
- mAlarmButton->setChecked( false );
+ if ( mType == "Todo" &&
+ alarm->hasEndOffset() && alarm->endOffset().asSeconds() <= 0 ) {
+ simple = true;
}
- mAlarmEditButton->setEnabled( false );
- } else if ( mAlarmList.count() > 1 ) {
- mAlarmStack->raiseWidget( AdvancedAlarmLabel );
- mAlarmInfoLabel->setText( i18n("1 advanced reminder configured",
- "%n advanced reminders configured",
- mAlarmList.count() ) );
- mAlarmEditButton->setEnabled( true );
- } else {
- Alarm *alarm = mAlarmList.first();
- // Check if its the trivial type of alarm, which can be
- // configured with a simply spin box...
+ }
+ return simple;
+}
- if ( alarm->type() == Alarm::Display && alarm->text().isEmpty()
- && alarm->repeatCount() == 0 && !alarm->hasTime()
- && alarm->hasStartOffset() && alarm->startOffset().asSeconds() < 0 ) {
- mAlarmStack->raiseWidget( SimpleAlarmPage );
- mAlarmButton->setChecked( true );
- int offset = alarm->startOffset().asSeconds();
+static TQString etc = i18n( "elipsis", "..." );
+void KOEditorGeneral::updateAlarmWidgets( Incidence *incidence )
+{
+ uint maxLen = 75; //TODO: compute from the font and dialog width
+
+ if ( incidence ) {
+ mAlarmButton->setChecked( incidence->isAlarmEnabled() );
+ }
+ if ( mAlarmList.isEmpty() ) {
+ mAlarmIsSimple = true;
+ mSimpleAlarmBox->show();
+ bool on;
+ if ( mType == "Event" ) {
+ on = KOPrefs::instance()->defaultEventReminders();
+ } else if ( mType == "Todo" ) {
+ on = KOPrefs::instance()->defaultTodoReminders();
+ } else {
+ on = false;
+ }
+ mAlarmButton->setChecked( on );
+ mAlarmAdvancedButton->setEnabled( on );
+ } else if ( mAlarmList.count() > 1 ) {
+ mAlarmIsSimple = false;
+ mAlarmAdvancedButton->setEnabled( true );
+ mSimpleAlarmBox->hide();
+ if ( incidence ) {
+ TQString remStr = IncidenceFormatter::reminderStringList( incidence ).join( ", " );
+ if ( remStr.length() > maxLen ) {
+ maxLen -= etc.length();
+ remStr = remStr.left( maxLen );
+ remStr += etc;
+ }
+ mAlarmInfoLabel->setText( i18n( "Triggers %1" ).arg( remStr ) );
+ }
+ } else { // alarm count is 1
+ Alarm *alarm = mAlarmList.first();
+ if ( isSimpleAlarm( alarm ) ) {
+ mAlarmIsSimple = true;
+ mSimpleAlarmBox->show();
+ int offset;
+ if ( mType == "Event" ) {
+ offset = alarm->startOffset().asSeconds();
+ mAlarmInfoLabel->setText( i18n( "before the start" ) );
+ }
+ if ( mType == "Todo" ) {
+ if ( alarm->hasStartOffset() ) {
+ offset = alarm->startOffset().asSeconds();
+ mAlarmInfoLabel->setText( i18n( "before the start" ) );
+ } else {
+ offset = alarm->endOffset().asSeconds();
+ mAlarmInfoLabel->setText( i18n( "before the due time" ) );
+ }
+ }
offset = offset / -60; // make minutes
int useoffset = offset;
- if (offset % (24*60) == 0) { // divides evenly into days?
+ if ( offset == 0 ) {
+ mAlarmIncrCombo->setCurrentItem( 0 ); // use minute units for 0 offset
+ } else if (offset % (24*60) == 0) { // divides evenly into days?
useoffset = offset / (24*60);
mAlarmIncrCombo->setCurrentItem(2);
} else if (offset % 60 == 0) { // divides evenly into hours?
@@ -388,97 +460,105 @@ void KOEditorGeneral::updateAlarmWidgets()
}
mAlarmTimeEdit->setValue( useoffset );
} else {
- mAlarmStack->raiseWidget( AdvancedAlarmLabel );
- mAlarmInfoLabel->setText( i18n("1 advanced reminder configured") );
- mAlarmEditButton->setEnabled( true );
+ mAlarmIsSimple = false;
+ mAlarmAdvancedButton->setEnabled( true );
+ mSimpleAlarmBox->hide();
+ if ( incidence ) {
+ TQString remStr = IncidenceFormatter::reminderStringList( incidence ).first();
+ mAlarmInfoLabel->setText( i18n( "Triggers %1" ).arg( remStr ) );
+ }
}
}
}
-void KOEditorGeneral::readIncidence(Incidence *event, Calendar *calendar)
+void KOEditorGeneral::readIncidence( Incidence *incidence, Calendar *calendar )
{
- mSummaryEdit->setText(event->summary());
- mLocationEdit->setText(event->location());
+ mSummaryEdit->setText( incidence->summary() );
+ mLocationEdit->setText( incidence->location() );
+ mDescriptionEdit->setText( incidence->description() );
- mDescriptionEdit->setText(event->description());
-
-#if 0
- // organizer information
- mOwnerLabel->setText(i18n("Owner: ") + event->organizer().fullName() );
-#endif
-
- mSecrecyCombo->setCurrentItem(event->secrecy());
+ mSecrecyCombo->setCurrentItem( incidence->secrecy() );
// set up alarm stuff
mAlarmList.clear();
Alarm::List::ConstIterator it;
- Alarm::List alarms = event->alarms();
+ Alarm::List alarms = incidence->alarms();
for( it = alarms.begin(); it != alarms.end(); ++it ) {
Alarm *al = new Alarm( *(*it) );
al->setParent( 0 );
mAlarmList.append( al );
}
updateDefaultAlarmTime();
- updateAlarmWidgets();
+ updateAlarmWidgets( incidence );
- setCategories(event->categories());
+ setCategories( incidence->categories() );
- mAttachments->readIncidence( event );
+ mAttachments->readIncidence( incidence );
- TQString resLabel = KOHelper::resourceLabel( calendar, event );
+ TQString resLabel = IncidenceFormatter::resourceString( calendar, incidence );
if ( !resLabel.isEmpty() ) {
mResourceLabel->setText( i18n( "Calendar: %1" ).arg( resLabel ) );
mResourceLabel->show();
}
}
-Alarm *KOEditorGeneral::alarmFromSimplePage() const
+Alarm *KOEditorGeneral::alarmFromSimplePage( Incidence *incidence ) const
{
if ( mAlarmButton->isChecked() ) {
Alarm *alarm = new Alarm( 0 );
- alarm->setDisplayAlarm("");
+ alarm->setDisplayAlarm( "" );
alarm->setEnabled(true);
TQString tmpStr = mAlarmTimeEdit->text();
int j = mAlarmTimeEdit->value() * -60;
- if (mAlarmIncrCombo->currentItem() == 1)
+ if ( mAlarmIncrCombo->currentItem() == 1 ) {
j = j * 60;
- else if (mAlarmIncrCombo->currentItem() == 2)
+ } else if ( mAlarmIncrCombo->currentItem() == 2 ) {
j = j * (60 * 24);
- alarm->setStartOffset( j );
+ }
+ if ( mType == "Event" ) {
+ alarm->setStartOffset( j );
+ }
+ if ( mType == "Todo" ) {
+ Todo *todo = static_cast<Todo *>( incidence );
+ if ( todo && todo->hasStartDate() && !todo->hasDueDate() ) {
+ alarm->setStartOffset( j );
+ } else {
+ alarm->setEndOffset( j );
+ }
+ }
return alarm;
} else {
return 0;
}
}
-void KOEditorGeneral::writeIncidence(Incidence *event)
+void KOEditorGeneral::writeIncidence( Incidence *incidence )
{
-// kdDebug(5850) << "KOEditorGeneral::writeEvent()" << endl;
-
- event->setSummary(mSummaryEdit->text());
- event->setLocation(mLocationEdit->text());
- event->setDescription(mDescriptionEdit->text());
- event->setCategories(mCategories);
- event->setSecrecy(mSecrecyCombo->currentItem());
+ incidence->setSummary(mSummaryEdit->text());
+ incidence->setLocation(mLocationEdit->text());
+ incidence->setDescription(mDescriptionEdit->text());
+ incidence->setCategories(mCategories);
+ incidence->setSecrecy(mSecrecyCombo->currentItem());
// alarm stuff
- event->clearAlarms();
- if ( mAlarmStack->id( mAlarmStack->visibleWidget() ) == SimpleAlarmPage ) {
- Alarm *al = alarmFromSimplePage();
+ incidence->clearAlarms();
+ if ( mAlarmIsSimple ) {
+ Alarm *al = alarmFromSimplePage( incidence );
if ( al ) {
- al->setParent( event );
- event->addAlarm( al );
+ al->setParent( incidence );
+ al->setEnabled( mAlarmButton->isChecked() );
+ incidence->addAlarm( al );
}
} else {
// simply assign the list of alarms
Alarm::List::ConstIterator it;
for( it = mAlarmList.begin(); it != mAlarmList.end(); ++it ) {
Alarm *al = new Alarm( *(*it) );
- al->setParent( event );
- al->setEnabled( true );
- event->addAlarm( al );
+ al->setParent( incidence );
+ al->setEnabled( mAlarmButton->isChecked() );
+ incidence->addAlarm( al );
}
}
- mAttachments->writeIncidence( event );
+ mAttachments->writeIncidence( incidence );
}
void KOEditorGeneral::setSummary( const TQString &text )
@@ -499,7 +579,7 @@ TQObject *KOEditorGeneral::typeAheadReceiver() const
void KOEditorGeneral::updateAttendeeSummary(int count)
{
if ( count <= 0 )
- mAttendeeSummaryLabel->setText( "No attendees" );
+ mAttendeeSummaryLabel->setText( i18n("No attendees") );
else
mAttendeeSummaryLabel->setText( i18n( "One attendee", "%n attendees", count ) );
}
diff --git a/korganizer/koeditorgeneral.h b/korganizer/koeditorgeneral.h
index b1fffc26..1a9d6017 100644
--- a/korganizer/koeditorgeneral.h
+++ b/korganizer/koeditorgeneral.h
@@ -28,10 +28,10 @@
class TQWidget;
class TQBoxLayout;
+class TQHBox;
class TQLineEdit;
class TQLabel;
class TQCheckBox;
-class TQWidgetStack;
class TQSpinBox;
class TQPushButton;
class TQComboBox;
@@ -41,8 +41,8 @@ class KURL;
class KOEditorAttachments;
namespace KCal {
-class Incidence;
-class Calendar;
+ class Incidence;
+ class Calendar;
}
using namespace KCal;
@@ -77,10 +77,10 @@ class KOEditorGeneral : public QObject
/** Set widgets to default values */
void setDefaults(bool allDay);
- /** Read event object and setup widgets accordingly */
- void readIncidence(Incidence *event, Calendar *calendar);
- /** Write event settings to event object */
- void writeIncidence(Incidence *);
+ /** Read incidence object and setup widgets accordingly */
+ void readIncidence( Incidence *incidence, Calendar *calendar );
+ /** Write incidence settings to incidence object */
+ void writeIncidence( Incidence *incidence );
/** Check if the input is valid. */
bool validateInput() { return true; }
@@ -96,14 +96,14 @@ class KOEditorGeneral : public QObject
public slots:
void setCategories(const TQStringList &categories);
void selectCategories();
+ void setType( const TQCString &type );
void addAttachments( const TQStringList &attachments,
const TQStringList& mimeTypes = TQStringList(),
bool inlineAttachment = false );
-
protected slots:
void editAlarms();
- void updateAlarmWidgets();
+ void updateAlarmWidgets( Incidence *incidence );
void updateDefaultAlarmTime();
void updateAttendeeSummary( int count );
@@ -112,19 +112,19 @@ class KOEditorGeneral : public QObject
void updateCategoryConfig();
void focusReceivedSignal();
void openURL( const KURL & );
- protected:
- Alarm *alarmFromSimplePage() const;
+ protected:
TQLineEdit *mSummaryEdit;
TQLineEdit *mLocationEdit;
TQLabel *mAttendeeSummaryLabel;
+ TQLabel *mRecEditLabel;
+ TQPushButton *mRecEditButton;
TQLabel *mAlarmBell;
- TQWidgetStack *mAlarmStack;
TQLabel *mAlarmInfoLabel;
TQCheckBox *mAlarmButton;
TQSpinBox *mAlarmTimeEdit;
TQComboBox *mAlarmIncrCombo;
- TQPushButton *mAlarmEditButton;
+ TQPushButton *mAlarmAdvancedButton;
KTextEdit *mDescriptionEdit;
TQLabel *mOwnerLabel;
TQComboBox *mSecrecyCombo;
@@ -133,10 +133,14 @@ class KOEditorGeneral : public QObject
KOEditorAttachments *mAttachments;
TQLabel *mResourceLabel;
- enum AlarmStackPages { SimpleAlarmPage, AdvancedAlarmLabel };
-
private:
+ Alarm *alarmFromSimplePage( Incidence *incidence ) const;
+ bool isSimpleAlarm( Alarm *alarm ) const;
+
+ bool mAlarmIsSimple;
+ TQHBox *mSimpleAlarmBox;
TQStringList mCategories;
+ TQCString mType; // as in Incidence::type()
KCal::Alarm::List mAlarmList;
};
diff --git a/korganizer/koeditorgeneralevent.cpp b/korganizer/koeditorgeneralevent.cpp
index 24e8b4ca..0411c2f8 100644
--- a/korganizer/koeditorgeneralevent.cpp
+++ b/korganizer/koeditorgeneralevent.cpp
@@ -39,7 +39,6 @@
#include <kdebug.h>
#include <kglobal.h>
#include <klocale.h>
-#include <kiconloader.h>
#include <kmessagebox.h>
#include <kfiledialog.h>
#include <kstandarddirs.h>
@@ -52,6 +51,7 @@
#include <libkdepim/kdateedit.h>
#include "koprefs.h"
+#include "koglobals.h"
#include "koeditorgeneralevent.h"
#include "koeditorgeneralevent.moc"
@@ -78,18 +78,15 @@ void KOEditorGeneralEvent::finishSetup()
TQWidget::setTabOrder( mStartTimeEdit, mEndDateEdit );
TQWidget::setTabOrder( mEndDateEdit, mEndTimeEdit );
TQWidget::setTabOrder( mEndTimeEdit, mAlldayEventCheckbox );
- TQWidget::setTabOrder( mAlldayEventCheckbox, mAlarmButton );
+ TQWidget::setTabOrder( mAlldayEventCheckbox, mRecEditButton );
+ TQWidget::setTabOrder( mRecEditButton, mAlarmButton );
TQWidget::setTabOrder( mAlarmButton, mAlarmTimeEdit );
TQWidget::setTabOrder( mAlarmTimeEdit, mAlarmIncrCombo );
-// TQWidget::setTabOrder( mAlarmIncrCombo, mAlarmSoundButton );
- TQWidget::setTabOrder( mAlarmIncrCombo, mAlarmEditButton );
-// TQWidget::setTabOrder( mAlarmSoundButton, mAlarmProgramButton );
-// TQWidget::setTabOrder( mAlarmProgramButton, mFreeTimeCombo );
- TQWidget::setTabOrder( mAlarmEditButton, mFreeTimeCombo );
+ TQWidget::setTabOrder( mAlarmIncrCombo, mAlarmAdvancedButton );
+ TQWidget::setTabOrder( mAlarmAdvancedButton, mFreeTimeCombo );
TQWidget::setTabOrder( mFreeTimeCombo, mDescriptionEdit );
TQWidget::setTabOrder( mDescriptionEdit, mCategoriesButton );
TQWidget::setTabOrder( mCategoriesButton, mSecrecyCombo );
-// TQWidget::setTabOrder( mSecrecyCombo, mDescriptionEdit );
mSummaryEdit->setFocus();
}
@@ -121,7 +118,6 @@ void KOEditorGeneralEvent::initTime(TQWidget *parent,TQBoxLayout *topLayout)
mStartTimeEdit = new KTimeEdit(timeBoxFrame);
layoutTimeBox->addWidget(mStartTimeEdit,0,2);
-
mEndDateLabel = new TQLabel(i18n("&End:"),timeBoxFrame);
layoutTimeBox->addWidget(mEndDateLabel,1,0);
@@ -151,16 +147,19 @@ void KOEditorGeneralEvent::initTime(TQWidget *parent,TQBoxLayout *topLayout)
connect(mEndDateEdit, TQT_SIGNAL(dateChanged(const TQDate&)),
this, TQT_SLOT(endDateChanged(const TQDate&)));
+ TQLabel *label = new TQLabel( i18n( "Recurrence:" ), timeBoxFrame );
+ layoutTimeBox->addWidget( label, 2, 0 );
TQBoxLayout *recLayout = new TQHBoxLayout();
layoutTimeBox->addMultiCellLayout( recLayout, 2, 2, 1, 4 );
- mRecurrenceSummary = new TQLabel( TQString(), timeBoxFrame );
- recLayout->addWidget( mRecurrenceSummary );
- TQPushButton *recEditButton = new TQPushButton( i18n("Edit..."), timeBoxFrame );
- recLayout->addWidget( recEditButton );
- connect( recEditButton, TQT_SIGNAL(clicked()), TQT_SIGNAL(editRecurrence()) );
+ mRecEditButton = new TQPushButton( timeBoxFrame );
+ mRecEditButton->setIconSet( KOGlobals::self()->smallIconSet( "recur", 16 ) );
+ recLayout->addWidget( mRecEditButton );
+ connect( mRecEditButton, TQT_SIGNAL(clicked()), TQT_SIGNAL(editRecurrence()) );
+ mRecEditLabel = new TQLabel( TQString(), timeBoxFrame );
+ recLayout->addWidget( mRecEditLabel );
recLayout->addStretch( 1 );
- TQLabel *label = new TQLabel( i18n("Reminder:"), timeBoxFrame );
+ label = new TQLabel( i18n("Reminder:"), timeBoxFrame );
layoutTimeBox->addWidget( label, 3, 0 );
TQBoxLayout *alarmLineLayout = new TQHBoxLayout();
layoutTimeBox->addMultiCellLayout( alarmLineLayout, 3, 3, 1, 4 );
@@ -230,7 +229,6 @@ void KOEditorGeneralEvent::timeStuffDisable(bool disable)
void KOEditorGeneralEvent::associateTime(bool time)
{
timeStuffDisable(time);
- //if(alarmButton->isChecked()) alarmStuffDisable(noTime);
allDayChanged(time);
}
@@ -317,7 +315,7 @@ void KOEditorGeneralEvent::setDefaults( const TQDateTime &from,
setDateTimes(from,to);
}
-void KOEditorGeneralEvent::readEvent( Event *event, Calendar *calendar, bool tmpl )
+void KOEditorGeneralEvent::readEvent( Event *event, Calendar *calendar, const TQDate &date, bool tmpl )
{
TQString tmpStr;
@@ -325,8 +323,26 @@ void KOEditorGeneralEvent::readEvent( Event *event, Calendar *calendar, bool tmp
timeStuffDisable(event->doesFloat());
if ( !tmpl ) {
+ TQDateTime startDT = event->dtStart();
+ TQDateTime endDT = event->dtEnd();
+ if ( event->doesRecur() && date.isValid() ) {
+ // Consider the active date when editing recurring Events.
+ TQDateTime kdt( date, TQTime( 0, 0, 0 ) );
+ const int eventLength = startDT.daysTo( endDT );
+ kdt = kdt.addSecs( -1 );
+ startDT.setDate( event->recurrence()->getNextDateTime( kdt ).date() );
+ if ( event->hasEndDate() ) {
+ endDT.setDate( startDT.addDays( eventLength ).date() );
+ } else {
+ if ( event->hasDuration() ) {
+ endDT = startDT.addSecs( event->duration() );
+ } else {
+ endDT = startDT;
+ }
+ }
+ }
// the rest is for the events only
- setDateTimes(event->dtStart(),event->dtEnd());
+ setDateTimes( startDT, endDT );
}
switch( event->transparency() ) {
@@ -338,11 +354,13 @@ void KOEditorGeneralEvent::readEvent( Event *event, Calendar *calendar, bool tmp
break;
}
- mRecurrenceSummary->setText( IncidenceFormatter::recurrenceString( event ) );
+ updateRecurrenceSummary( event );
Attendee *me = event->attendeeByMails( KOPrefs::instance()->allEmails() );
- if ( me && (me->status() == Attendee::NeedsAction || me->status() == Attendee::Tentative ||
- me->status() == Attendee::InProcess) ) {
+ if ( event->attendeeCount() > 1 &&
+ me && ( me->status() == Attendee::NeedsAction ||
+ me->status() == Attendee::Tentative ||
+ me->status() == Attendee::InProcess ) ) {
mInvitationBar->show();
} else {
mInvitationBar->hide();
@@ -509,16 +527,22 @@ bool KOEditorGeneralEvent::validateInput()
endDt.setTime(mEndTimeEdit->getTime());
}
- if (startDt > endDt) {
- KMessageBox::sorry(0,i18n("The event ends before it starts.\n"
- "Please correct dates and times."));
+ if ( startDt > endDt ) {
+ KMessageBox::sorry(
+ 0,
+ i18n( "The event ends before it starts.\n"
+ "Please correct dates and times." ) );
return false;
}
return KOEditorGeneral::validateInput();
}
-void KOEditorGeneralEvent::updateRecurrenceSummary(const TQString & summary)
+void KOEditorGeneralEvent::updateRecurrenceSummary( Event *event )
{
- mRecurrenceSummary->setText( summary );
+ if ( event->doesRecur() ) {
+ mRecEditLabel->setText( IncidenceFormatter::recurrenceString( event ) );
+ } else {
+ mRecEditLabel->setText( TQString() );
+ }
}
diff --git a/korganizer/koeditorgeneralevent.h b/korganizer/koeditorgeneralevent.h
index a13fa47c..57ffba8d 100644
--- a/korganizer/koeditorgeneralevent.h
+++ b/korganizer/koeditorgeneralevent.h
@@ -58,14 +58,14 @@ class KOEditorGeneralEvent : public KOEditorGeneral
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 *event, Calendar *calendar, bool tmpl = false );
+ void readEvent( Event *event, Calendar *calendar, const TQDate &date, bool tmpl = false );
/** Write event settings to event object */
void writeEvent( Event * );
/** Check if the input is valid. */
bool validateInput();
- void updateRecurrenceSummary( const TQString &summary );
+ void updateRecurrenceSummary( Event *event );
TQFrame* invitationBar() const { return mInvitationBar; }
@@ -102,7 +102,6 @@ class KOEditorGeneralEvent : public KOEditorGeneral
TQLabel *mDurationLabel;
TQCheckBox *mAlldayEventCheckbox;
TQComboBox *mFreeTimeCombo;
- TQLabel *mRecurrenceSummary;
TQFrame *mInvitationBar;
// current start and end date and time
diff --git a/korganizer/koeditorgeneraljournal.cpp b/korganizer/koeditorgeneraljournal.cpp
index 62041719..0a4e5ec3 100644
--- a/korganizer/koeditorgeneraljournal.cpp
+++ b/korganizer/koeditorgeneraljournal.cpp
@@ -45,10 +45,11 @@
#include <tqwhatsthis.h>
-KOEditorGeneralJournal::KOEditorGeneralJournal( TQObject *parent,
+KOEditorGeneralJournal::KOEditorGeneralJournal( TQWidget *parent,
const char *name )
- : TQObject( parent, name )
+ : KOEditorGeneral( parent, name )
{
+ setType( "Journal" );
}
KOEditorGeneralJournal::~KOEditorGeneralJournal()
@@ -58,7 +59,7 @@ KOEditorGeneralJournal::~KOEditorGeneralJournal()
void KOEditorGeneralJournal::initTitle( TQWidget *parent, TQBoxLayout *topLayout )
{
TQHBoxLayout *hbox = new TQHBoxLayout( topLayout );
-
+
TQString whatsThis = i18n("Sets the title of this journal.");
TQLabel *summaryLabel = new TQLabel( i18n("T&itle:"), parent );
TQWhatsThis::add( summaryLabel, whatsThis );
@@ -78,19 +79,19 @@ void KOEditorGeneralJournal::initDate( TQWidget *parent, TQBoxLayout *topLayout
{
// TQBoxLayout *dateLayout = new TQVBoxLayout(topLayout);
TQBoxLayout *dateLayout = new TQHBoxLayout( topLayout );
-
+
mDateLabel = new TQLabel( i18n("&Date:"), parent);
dateLayout->addWidget( mDateLabel );
mDateEdit = new KDateEdit( parent );
dateLayout->addWidget( mDateEdit );
mDateLabel->setBuddy( mDateEdit );
-
+
dateLayout->addStretch();
-
+
mTimeCheckBox = new TQCheckBox( i18n("&Time: "), parent );
dateLayout->addWidget( mTimeCheckBox );
-
+
mTimeEdit = new KTimeEdit( parent );
dateLayout->addWidget( mTimeEdit );
connect( mTimeCheckBox, TQT_SIGNAL(toggled(bool)),
@@ -135,7 +136,7 @@ void KOEditorGeneralJournal::setDefaults( const TQDate &date )
setDate( date );
}
-void KOEditorGeneralJournal::readJournal( Journal *journal, bool tmpl )
+void KOEditorGeneralJournal::readJournal( Journal *journal, const TQDate &, bool tmpl )
{
setSummary( journal->summary() );
if ( !tmpl ) {
@@ -143,10 +144,10 @@ void KOEditorGeneralJournal::readJournal( Journal *journal, bool tmpl )
if ( !journal->doesFloat() ) {
kdDebug()<<"KOEditorGeneralJournal::readJournal, does not float, time="<<(journal->dtStart().time().toString())<<endl;
setTime( journal->dtStart().time() );
- } else {
+ } else {
kdDebug()<<"KOEditorGeneralJournal::readJournal, does float"<<endl;
setTime( TQTime( -1, -1, -1 ) );
- }
+ }
}
setDescription( journal->description() );
}
@@ -156,7 +157,7 @@ void KOEditorGeneralJournal::writeJournal( Journal *journal )
// kdDebug(5850) << "KOEditorGeneralJournal::writeIncidence()" << endl;
journal->setSummary( mSummaryEdit->text() );
journal->setDescription( mDescriptionEdit->text() );
-
+
TQDateTime tmpDT( mDateEdit->date(), TQTime(0,0,0) );
bool hasTime = mTimeCheckBox->isChecked();
journal->setFloats( !hasTime );
diff --git a/korganizer/koeditorgeneraljournal.h b/korganizer/koeditorgeneraljournal.h
index 28827c8c..649a6d34 100644
--- a/korganizer/koeditorgeneraljournal.h
+++ b/korganizer/koeditorgeneraljournal.h
@@ -25,6 +25,8 @@
#ifndef KOEDITORGENERALJOURNAL_H
#define KOEDITORGENERALJOURNAL_H
+#include "koeditorgeneral.h"
+
#include <tqobject.h>
#include <tqdatetime.h>
@@ -43,11 +45,11 @@ class Journal;
}
using namespace KCal;
-class KOEditorGeneralJournal : public QObject
+class KOEditorGeneralJournal : public KOEditorGeneral
{
- Q_OBJECT
+ Q_OBJECT
public:
- KOEditorGeneralJournal ( TQObject* parent=0, const char* name=0 );
+ KOEditorGeneralJournal ( TQWidget *parent=0, const char* name=0 );
virtual ~KOEditorGeneralJournal();
void initDate( TQWidget *, TQBoxLayout * );
@@ -59,7 +61,7 @@ class KOEditorGeneralJournal : public QObject
void setDate( const TQDate &date );
void setTime( const TQTime &time );
/** Read journal object and setup widgets accordingly */
- void readJournal( Journal *, bool tmpl = false );
+ void readJournal( Journal *, const TQDate &, bool tmpl = false );
/** Write journal settings to event object */
void writeJournal( Journal * );
diff --git a/korganizer/koeditorgeneraltodo.cpp b/korganizer/koeditorgeneraltodo.cpp
index dd2a77b5..d659e8e9 100644
--- a/korganizer/koeditorgeneraltodo.cpp
+++ b/korganizer/koeditorgeneraltodo.cpp
@@ -38,13 +38,13 @@
#include <kglobal.h>
#include <klocale.h>
-#include <kiconloader.h>
#include <kmessagebox.h>
#include <kdebug.h>
#include <kstandarddirs.h>
#include <kfiledialog.h>
#include <ktextedit.h>
+#include <libkcal/incidenceformatter.h>
#include <libkcal/todo.h>
#include <libkdepim/kdateedit.h>
@@ -56,10 +56,10 @@
#include "koeditorgeneraltodo.h"
#include "koeditorgeneraltodo.moc"
-KOEditorGeneralTodo::KOEditorGeneralTodo(TQObject* parent,
- const char* name)
- : KOEditorGeneral( parent, name)
+KOEditorGeneralTodo::KOEditorGeneralTodo( TQObject *parent, const char *name )
+ : KOEditorGeneral( parent, name )
{
+ setType( "Todo" );
}
KOEditorGeneralTodo::~KOEditorGeneralTodo()
@@ -76,19 +76,17 @@ void KOEditorGeneralTodo::finishSetup()
TQWidget::setTabOrder( mDueCheck, mDueDateEdit );
TQWidget::setTabOrder( mDueDateEdit, mDueTimeEdit );
TQWidget::setTabOrder( mDueTimeEdit, mTimeButton );
- TQWidget::setTabOrder( mTimeButton, mCompletedCombo );
+ TQWidget::setTabOrder( mTimeButton, mRecEditButton );
+ TQWidget::setTabOrder( mRecEditButton, mCompletedToggle );
+ TQWidget::setTabOrder( mCompletedToggle, mCompletedCombo );
TQWidget::setTabOrder( mCompletedCombo, mPriorityCombo );
TQWidget::setTabOrder( mPriorityCombo, mAlarmButton );
TQWidget::setTabOrder( mAlarmButton, mAlarmTimeEdit );
TQWidget::setTabOrder( mAlarmTimeEdit, mAlarmIncrCombo );
-// TQWidget::setTabOrder( mAlarmIncrCombo, mAlarmSoundButton );
- TQWidget::setTabOrder( mAlarmIncrCombo, mAlarmEditButton );
-// TQWidget::setTabOrder( mAlarmSoundButton, mAlarmProgramButton );
-// TQWidget::setTabOrder( mAlarmProgramButton, mDescriptionEdit );
- TQWidget::setTabOrder( mAlarmEditButton, mDescriptionEdit );
+ TQWidget::setTabOrder( mAlarmIncrCombo, mAlarmAdvancedButton );
+ TQWidget::setTabOrder( mAlarmAdvancedButton, mDescriptionEdit );
TQWidget::setTabOrder( mDescriptionEdit, mCategoriesButton );
TQWidget::setTabOrder( mCategoriesButton, mSecrecyCombo );
-// TQWidget::setTabOrder( mSecrecyCombo, mDescriptionEdit );
mSummaryEdit->setFocus();
}
@@ -134,7 +132,6 @@ void KOEditorGeneralTodo::initTime(TQWidget *parent,TQBoxLayout *topLayout)
TQWhatsThis::add( mDueCheck, whatsThis );
layoutTimeBox->addWidget(mDueCheck,1,0);
connect(mDueCheck,TQT_SIGNAL(toggled(bool)),TQT_SLOT(enableDueEdit(bool)));
- connect(mDueCheck,TQT_SIGNAL(toggled(bool)),TQT_SLOT(showAlarm()));
connect(mDueCheck,TQT_SIGNAL(toggled(bool)),TQT_SIGNAL(dueDateEditToggle(bool)));
connect(mDueCheck,TQT_SIGNAL(toggled(bool)),TQT_SLOT(dateChanged()));
@@ -153,13 +150,31 @@ void KOEditorGeneralTodo::initTime(TQWidget *parent,TQBoxLayout *topLayout)
TQWhatsThis::add( mTimeButton,
i18n("Sets whether or not this to-do's start and due dates "
"have times associated with them.") );
- layoutTimeBox->addMultiCellWidget(mTimeButton,2,2,0,2);
-
+ layoutTimeBox->addWidget( mTimeButton, 0, 3 );
connect(mTimeButton,TQT_SIGNAL(toggled(bool)),TQT_SLOT(enableTimeEdits(bool)));
connect(mTimeButton,TQT_SIGNAL(toggled(bool)),TQT_SLOT(dateChanged()));
+ TQLabel *label = new TQLabel( i18n( "Recurrence:" ), timeBoxFrame );
+ layoutTimeBox->addWidget( label, 3, 0 );
+ TQBoxLayout *recLayout = new TQHBoxLayout();
+ layoutTimeBox->addMultiCellLayout( recLayout, 3, 3, 1, 4 );
+ mRecEditButton = new TQPushButton( timeBoxFrame );
+ mRecEditButton->setIconSet( KOGlobals::self()->smallIconSet( "recur", 16 ) );
+ recLayout->addWidget( mRecEditButton );
+ connect( mRecEditButton, TQT_SIGNAL(clicked()), TQT_SIGNAL(editRecurrence()) );
+ mRecEditLabel = new TQLabel( TQString(), timeBoxFrame );
+ recLayout->addWidget( mRecEditLabel );
+ recLayout->addStretch( 1 );
+
+ label = new TQLabel( i18n("Reminder:"), timeBoxFrame );
+ layoutTimeBox->addWidget( label, 4, 0 );
+ TQBoxLayout *alarmLineLayout = new TQHBoxLayout();
+ layoutTimeBox->addMultiCellLayout( alarmLineLayout, 4, 4, 1, 4 );
+ initAlarm( timeBoxFrame, alarmLineLayout );
+ alarmLineLayout->addStretch( 1 );
+
// some more layouting
- layoutTimeBox->setColStretch(3,1);
+ layoutTimeBox->setColStretch( 3, 1 );
TQBoxLayout *secLayout = new TQHBoxLayout();
layoutTimeBox->addLayout( secLayout, 0, 4 );
@@ -167,54 +182,73 @@ void KOEditorGeneralTodo::initTime(TQWidget *parent,TQBoxLayout *topLayout)
}
-void KOEditorGeneralTodo::initCompletion(TQWidget *parent, TQBoxLayout *topLayout)
+void KOEditorGeneralTodo::initCompletion( TQWidget *parent, TQBoxLayout *topLayout )
{
- TQString whatsThis = i18n("Sets the current completion status of this to-do "
- "as a percentage.");
- mCompletedCombo = new TQComboBox(parent);
- TQWhatsThis::add( mCompletedCombo, whatsThis );
- for (int i = 0; i <= 100; i+=10) {
+ TQHBoxLayout *completionLayout = new TQHBoxLayout( topLayout );
+
+ TQLabel *label = new TQLabel( i18n( "&Completed:" ), parent );
+ completionLayout->addWidget( label );
+
+ mCompletedToggle = new TQCheckBox( parent );
+ TQToolTip::add( mCompletedToggle,
+ i18n( "Toggle between 0% and 100% complete" ) );
+ TQWhatsThis::add( mCompletedToggle,
+ i18n( "Click this checkbox to toggle the completed percentage of the to-do "
+ "between 0% or 100%" ) );
+ connect( mCompletedToggle, TQT_SIGNAL(clicked()), TQT_SLOT(completedChanged()) );
+ completionLayout->addWidget( mCompletedToggle );
+ label->setBuddy( mCompletedToggle );
+
+ mCompletedCombo = new TQComboBox( parent );
+ TQToolTip::add( mCompletedCombo,
+ i18n( "Select the completed percentage" ) );
+ TQWhatsThis::add( mCompletedCombo,
+ i18n( "Use this combobox to set the completion percentage of the to-do." ) );
+ for ( int i = 0; i <= 100; i+=10 ) {
// xgettext:no-c-format
- TQString label = i18n("Percent complete", "%1 %").arg (i);
- mCompletedCombo->insertItem(label);
+ TQString label = i18n( "Percent complete", "%1 %" ).arg( i );
+ mCompletedCombo->insertItem( label );
}
- connect(mCompletedCombo,TQT_SIGNAL(activated(int)),TQT_SLOT(completedChanged(int)));
- topLayout->addWidget(mCompletedCombo);
+ connect( mCompletedCombo, TQT_SIGNAL(activated(int)), TQT_SLOT(completedChanged(int)) );
+ completionLayout->addWidget( mCompletedCombo );
+
+ mCompletedLabel = new TQLabel( i18n( "completed on", "on" ), parent );
+ mCompletedLabel->hide();
+ completionLayout->addWidget( mCompletedLabel );
- mCompletedLabel = new TQLabel(i18n("co&mpleted"),parent);
- topLayout->addWidget(mCompletedLabel);
- mCompletedLabel->setBuddy( mCompletedCombo );
mCompletionDateEdit = new KDateEdit( parent );
mCompletionDateEdit->hide();
- topLayout->addWidget( mCompletionDateEdit );
+ completionLayout->addWidget( mCompletionDateEdit );
+
mCompletionTimeEdit = new KTimeEdit( parent, TQTime() );
mCompletionTimeEdit->hide();
- topLayout->addWidget( mCompletionTimeEdit );
+ completionLayout->addWidget( mCompletionTimeEdit );
}
void KOEditorGeneralTodo::initPriority(TQWidget *parent, TQBoxLayout *topLayout)
{
- TQString whatsThis = i18n("Sets the priority of this to-do on a scale "
- "from one to nine, with one being the highest "
- "priority, five being a medium priority, and "
- "nine being the lowest. In programs that have a "
- "different scale, the numbers will be adjusted "
- "to match the appropriate scale.");
- TQLabel *priorityLabel = new TQLabel(i18n("&Priority:"),parent);
- topLayout->addWidget(priorityLabel);
-
- mPriorityCombo = new TQComboBox(parent);
- mPriorityCombo->insertItem(i18n("unspecified"));
- mPriorityCombo->insertItem(i18n("1 (highest)"));
- mPriorityCombo->insertItem(i18n("2"));
- mPriorityCombo->insertItem(i18n("3"));
- mPriorityCombo->insertItem(i18n("4"));
- mPriorityCombo->insertItem(i18n("5 (medium)"));
- mPriorityCombo->insertItem(i18n("6"));
- mPriorityCombo->insertItem(i18n("7"));
- mPriorityCombo->insertItem(i18n("8"));
- mPriorityCombo->insertItem(i18n("9 (lowest)"));
- topLayout->addWidget(mPriorityCombo);
+ TQLabel *priorityLabel = new TQLabel( i18n( "&Priority:" ), parent );
+ topLayout->addWidget( priorityLabel );
+
+ mPriorityCombo = new TQComboBox( parent );
+ TQToolTip::add( mPriorityCombo,
+ i18n( "Set the priority of the to-do" ) );
+ TQWhatsThis::add( mPriorityCombo,
+ i18n( "Sets the priority of this to-do on a scale from one to nine, "
+ "with one being the highest priority, five being a medium priority, "
+ "and nine being the lowest. In programs that have a different scale, "
+ "the numbers will be adjusted to match the appropriate scale." ) );
+ mPriorityCombo->insertItem( i18n( "unspecified" ) );
+ mPriorityCombo->insertItem( i18n( "1 (highest)" ) );
+ mPriorityCombo->insertItem( i18n( "2" ) );
+ mPriorityCombo->insertItem( i18n( "3" ) );
+ mPriorityCombo->insertItem( i18n( "4" ) );
+ mPriorityCombo->insertItem( i18n( "5 (medium)" ) );
+ mPriorityCombo->insertItem( i18n( "6" ) );
+ mPriorityCombo->insertItem( i18n( "7" ) );
+ mPriorityCombo->insertItem( i18n( "8" ) );
+ mPriorityCombo->insertItem( i18n( "9 (lowest)" ) );
+ topLayout->addWidget( mPriorityCombo );
priorityLabel->setBuddy( mPriorityCombo );
}
@@ -263,25 +297,29 @@ void KOEditorGeneralTodo::setDefaults( const TQDateTime &due, bool allDay )
}
mStartDateModified = false;
- mPriorityCombo->setCurrentItem(5);
+ mPriorityCombo->setCurrentItem( 5 );
- mCompletedCombo->setCurrentItem(0);
+ mCompletedToggle->setChecked( false );
+ mCompletedCombo->setCurrentItem( 0 );
}
-void KOEditorGeneralTodo::readTodo(Todo *todo, Calendar *calendar)
+void KOEditorGeneralTodo::readTodo(Todo *todo, Calendar *calendar, const TQDate &date )
{
KOEditorGeneral::readIncidence(todo, calendar);
TQDateTime dueDT;
if (todo->hasDueDate()) {
- enableAlarm( true );
dueDT = todo->dtDue();
- mDueDateEdit->setDate(todo->dtDue().date());
- mDueTimeEdit->setTime(todo->dtDue().time());
+ if ( todo->doesRecur() && date.isValid() ) {
+ TQDateTime dt( date, TQTime( 0, 0, 0 ) );
+ dt = dt.addSecs( -1 );
+ dueDT.setDate( todo->recurrence()->getNextDateTime( dt ).date() );
+ }
+ mDueDateEdit->setDate(dueDT.date());
+ mDueTimeEdit->setTime(dueDT.time());
mDueCheck->setChecked(true);
} else {
- enableAlarm( false );
mDueDateEdit->setEnabled(false);
mDueTimeEdit->setEnabled(false);
mDueDateEdit->setDate(TQDate::currentDate());
@@ -290,8 +328,13 @@ void KOEditorGeneralTodo::readTodo(Todo *todo, Calendar *calendar)
}
if (todo->hasStartDate()) {
- mStartDateEdit->setDate(todo->dtStart().date());
- mStartTimeEdit->setTime(todo->dtStart().time());
+ TQDateTime startDT = todo->dtStart();
+ if ( todo->doesRecur() && date.isValid() && todo->hasDueDate() ) {
+ int days = todo->dtStart( true ).daysTo( todo->dtDue( true ) );
+ startDT.setDate( date.addDays( -days ) );
+ }
+ mStartDateEdit->setDate(startDT.date());
+ mStartTimeEdit->setTime(startDT.time());
mStartCheck->setChecked(true);
} else {
mStartDateEdit->setEnabled(false);
@@ -303,10 +346,13 @@ void KOEditorGeneralTodo::readTodo(Todo *todo, Calendar *calendar)
mTimeButton->setChecked( !todo->doesFloat() );
+ updateRecurrenceSummary( todo );
+
mAlreadyComplete = false;
- mCompletedCombo->setCurrentItem(todo->percentComplete() / 10);
- if (todo->isCompleted() && todo->hasCompletedDate()) {
- mCompleted = todo->completed();
+ mCompletedCombo->setCurrentItem( todo->percentComplete() / 10 );
+ if ( todo->isCompleted() && todo->hasCompletedDate() ) {
+ mCompletedDateTime = todo->completed();
+ mCompletedToggle->setChecked( true );
mAlreadyComplete = true;
}
setCompletedDate();
@@ -369,25 +415,25 @@ void KOEditorGeneralTodo::writeTodo(Todo *todo)
if ( todo->doesRecur() && !mStartDateModified ) {
todo->setDtDue( tmpDueDT );
} else {
- todo->setDtDue( tmpDueDT, true );
- todo->setDtStart( tmpStartDT );
- todo->setDtRecurrence( tmpDueDT );
+ todo->setDtDue( tmpDueDT, true );
+ todo->setDtStart( tmpStartDT );
+ todo->setDtRecurrence( tmpDueDT );
}
todo->setPriority( mPriorityCombo->currentItem() );
// set completion state
- todo->setPercentComplete(mCompletedCombo->currentItem() * 10);
+ todo->setPercentComplete( mCompletedCombo->currentItem() * 10 );
- if (mCompletedCombo->currentItem() == 10 && mCompleted.isValid()) {
+ if (mCompletedCombo->currentItem() == 10 && mCompletedDateTime.isValid()) {
TQDateTime completed( mCompletionDateEdit->date(),
mCompletionTimeEdit->getTime() );
- int difference = mCompleted.secsTo( completed );
+ int difference = mCompletedDateTime.secsTo( completed );
if ( (difference < 60) && (difference > -60) &&
- (completed.time().minute() == mCompleted.time().minute() ) ) {
+ (completed.time().minute() == mCompletedDateTime.time().minute() ) ) {
// completion time wasn't changed substantially (only the seconds
// truncated, but that's an effect done by KTimeEdit automatically).
- completed = mCompleted;
+ completed = mCompletedDateTime;
}
todo->setCompleted( completed );
}
@@ -439,11 +485,6 @@ void KOEditorGeneralTodo::enableTimeEdits(bool enable)
}
}
-void KOEditorGeneralTodo::showAlarm()
-{
- enableAlarm( mDueCheck->isChecked() );
-}
-
bool KOEditorGeneralTodo::validateInput()
{
if (mDueCheck->isChecked()) {
@@ -491,10 +532,33 @@ bool KOEditorGeneralTodo::validateInput()
return KOEditorGeneral::validateInput();
}
-void KOEditorGeneralTodo::completedChanged(int index)
+void KOEditorGeneralTodo::updateRecurrenceSummary( Todo *todo )
+{
+ if ( todo->doesRecur() ) {
+ mRecEditLabel->setText( IncidenceFormatter::recurrenceString( todo ) );
+ } else {
+ mRecEditLabel->setText( TQString() );
+ }
+}
+
+void KOEditorGeneralTodo::completedChanged( int index )
{
- if (index == 10) {
- mCompleted = TQDateTime::currentDateTime();
+ if ( index == 10 ) {
+ mCompletedToggle->setChecked( true );
+ mCompletedDateTime = TQDateTime::currentDateTime();
+ } else {
+ mCompletedToggle->setChecked( false );
+ }
+ setCompletedDate();
+}
+
+void KOEditorGeneralTodo::completedChanged()
+{
+ if ( mCompletedToggle->isChecked() ) {
+ mCompletedCombo->setCurrentItem( 10 );
+ mCompletedDateTime = TQDateTime::currentDateTime();
+ } else {
+ mCompletedCombo->setCurrentItem( 0 );
}
setCompletedDate();
}
@@ -533,21 +597,20 @@ void KOEditorGeneralTodo::startDateModified()
void KOEditorGeneralTodo::setCompletedDate()
{
- if (mCompletedCombo->currentItem() == 10 && mCompleted.isValid()) {
- mCompletedLabel->setText(i18n("co&mpleted on"));
-// .arg(KGlobal::locale()->formatDateTime(mCompleted)));
+ if ( mCompletedCombo->currentItem() == 10 && mCompletedDateTime.isValid() ) {
+ mCompletedLabel->show();
mCompletionDateEdit->show();
mCompletionTimeEdit->show();
- mCompletionDateEdit->setDate( mCompleted.date() );
- mCompletionTimeEdit->setTime( mCompleted.time() );
+ mCompletionDateEdit->setDate( mCompletedDateTime.date() );
+ mCompletionTimeEdit->setTime( mCompletedDateTime.time() );
} else {
- mCompletedLabel->setText(i18n("co&mpleted"));
+ mCompletedLabel->hide();
mCompletionDateEdit->hide();
mCompletionTimeEdit->hide();
}
}
-void KOEditorGeneralTodo::modified (Todo* todo, int modification)
+void KOEditorGeneralTodo::modified (Todo* todo, KOGlobals::HowChanged modification)
{
switch (modification) {
case KOGlobals::PRIORITY_MODIFIED:
@@ -556,7 +619,8 @@ void KOEditorGeneralTodo::modified (Todo* todo, int modification)
case KOGlobals::COMPLETION_MODIFIED:
mCompletedCombo->setCurrentItem(todo->percentComplete() / 10);
if (todo->isCompleted() && todo->hasCompletedDate()) {
- mCompleted = todo->completed();
+ mCompletedDateTime = todo->completed();
+ mCompletedToggle->setChecked( true );
}
setCompletedDate();
break;
@@ -565,7 +629,7 @@ void KOEditorGeneralTodo::modified (Todo* todo, int modification)
break;
case KOGlobals::UNKNOWN_MODIFIED: // fall through
default:
- readTodo( todo, 0 );
+ readTodo( todo, 0, TQDate() );
break;
}
}
diff --git a/korganizer/koeditorgeneraltodo.h b/korganizer/koeditorgeneraltodo.h
index 7ebc1f7e..2d07ceca 100644
--- a/korganizer/koeditorgeneraltodo.h
+++ b/korganizer/koeditorgeneraltodo.h
@@ -25,6 +25,8 @@
#define _KOEDITORGENERALTODO_H
#include "koeditorgeneral.h"
+#include "koglobals.h"
+
#include <tqdatetime.h>
class KRestrictedLine;
@@ -54,30 +56,33 @@ class KOEditorGeneralTodo : public KOEditorGeneral
/** Set widgets to default values */
void setDefaults( const TQDateTime &due, bool allDay );
/** Read todo object and setup widgets accordingly */
- void readTodo(Todo *todo, Calendar *calendar);
+ void readTodo( Todo *todo, Calendar *calendar, const TQDate &date );
/** Write todo settings to event object */
void writeTodo(Todo *);
/** Check if the input is valid. */
bool validateInput();
+ void updateRecurrenceSummary( Todo *todo );
+
/** The todo has been modified externally */
- void modified (Todo*, int);
+ void modified( Todo *todo, KOGlobals::HowChanged modification );
signals:
void dueDateEditToggle( bool );
void dateTimeStrChanged( const TQString & );
void signalDateTimeChanged( const TQDateTime &, const TQDateTime & );
+ void editRecurrence();
protected slots:
- void completedChanged(int);
+ void completedChanged( int );
+ void completedChanged();
void dateChanged();
void startDateModified();
void enableDueEdit( bool enable );
void enableStartEdit( bool enable );
void enableTimeEdits( bool enable );
- void showAlarm();
protected:
void setCompletedDate();
@@ -92,6 +97,7 @@ class KOEditorGeneralTodo : public KOEditorGeneral
TQCheckBox *mDueCheck;
KDateEdit *mDueDateEdit;
KTimeEdit *mDueTimeEdit;
+ TQCheckBox *mCompletedToggle;
TQComboBox *mCompletedCombo;
TQLabel *mCompletedLabel;
TQLabel *mPriorityLabel;
@@ -102,7 +108,7 @@ class KOEditorGeneralTodo : public KOEditorGeneral
TQCheckBox *mStartCheck;
- TQDateTime mCompleted;
+ TQDateTime mCompletedDateTime;
};
diff --git a/korganizer/koeditorrecurrence.cpp b/korganizer/koeditorrecurrence.cpp
index 6f24446c..564c3953 100644
--- a/korganizer/koeditorrecurrence.cpp
+++ b/korganizer/koeditorrecurrence.cpp
@@ -593,7 +593,8 @@ ExceptionsWidget::ExceptionsWidget( TQWidget *parent, const char *name ) :
mExceptionDateEdit->setDate( TQDate::currentDate() );
boxLayout->addWidget( mExceptionDateEdit, 0, 0 );
- TQPushButton *addExceptionButton = new TQPushButton( i18n("&Add"), box );
+ TQPushButton *addExceptionButton = new TQPushButton(
+ i18n( "Add a new recurrence to the recurrence list", "&Add" ), box );
TQWhatsThis::add( addExceptionButton,
i18n("Add this date as an exception "
"to the recurrence rules for this event or to-do.") );
@@ -1073,6 +1074,9 @@ KOEditorRecurrence::KOEditorRecurrence( TQWidget* parent, const char *name ) :
mExceptionsButton = 0;
topLayout->addWidget( mExceptionsWidget, 3, 1 );
}
+
+ // set some initial defaults for the saved recurrence
+ mSaveRec.setDuration( -1 ); // never ending
}
KOEditorRecurrence::~KOEditorRecurrence()
@@ -1083,6 +1087,7 @@ void KOEditorRecurrence::setRecurrenceEnabled( bool enabled )
{
// kdDebug(5850) << "KOEditorRecurrence::setRecurrenceEnabled(): " << (enabled ? "on" : "off") << endl;
+ mEnabledCheck->setChecked( enabled );
mTimeGroupBox->setEnabled( enabled );
mRuleBox->setEnabled( enabled );
if ( mRecurrenceRangeWidget ) mRecurrenceRangeWidget->setEnabled( enabled );
@@ -1147,9 +1152,7 @@ void KOEditorRecurrence::setDefaults( const TQDateTime &from, const TQDateTime &
{
setDateTimes( from, to );
- bool enabled = false;
- mEnabledCheck->setChecked( enabled );
- setRecurrenceEnabled( enabled );
+ setRecurrenceEnabled( false );
mRecurrenceRange->setDefaults( from );
@@ -1200,8 +1203,6 @@ void KOEditorRecurrence::readIncidence(Incidence *incidence)
f = r->frequency();
}
-
- mEnabledCheck->setChecked( recurs );
setRecurrenceEnabled( recurs );
int recurrenceType = RecurrenceChooser::Weekly;
@@ -1438,10 +1439,218 @@ bool KOEditorRecurrence::doesRecur()
return mEnabledCheck->isChecked();
}
+void KOEditorRecurrence::saveValues()
+{
+ int duration = mRecurrenceRange->duration();
+ TQDate endDate;
+ if ( duration == 0 ) {
+ endDate = mRecurrenceRange->endDate();
+ }
+
+ int recurrenceType = mRecurrenceChooser->type();
+ if ( recurrenceType == RecurrenceChooser::Daily ) {
+ mSaveRec.setDaily( mDaily->frequency() );
+ } else if ( recurrenceType == RecurrenceChooser::Weekly ) {
+ mSaveRec.setWeekly( mWeekly->frequency(), mWeekly->days() );
+ } else if ( recurrenceType == RecurrenceChooser::Monthly ) {
+ mSaveRec.setMonthly( mMonthly->frequency() );
+
+ if ( mMonthly->byPos() ) {
+ int pos = mMonthly->count();
+
+ TQBitArray days( 7 );
+ days.fill( false );
+ days.setBit( mMonthly->weekday() - 1 );
+ mSaveRec.addMonthlyPos( pos, days );
+ } else {
+ // it's by day
+ mSaveRec.addMonthlyDate( mMonthly->day() );
+ }
+ } else if ( recurrenceType == RecurrenceChooser::Yearly ) {
+ mSaveRec.setYearly( mYearly->frequency() );
+
+ switch ( mYearly->getType() ) {
+ case RecurYearly::byMonth:
+ mSaveRec.addYearlyDate( mYearly->monthDay() );
+ mSaveRec.addYearlyMonth( mYearly->month() );
+ break;
+
+ case RecurYearly::byPos:
+ {
+ mSaveRec.addYearlyMonth( mYearly->posMonth() );
+ TQBitArray days( 7 );
+ days.fill( false );
+ days.setBit( mYearly->posWeekday() - 1 );
+ mSaveRec.addYearlyPos( mYearly->posCount(), days );
+ break;
+ }
+
+ case RecurYearly::byDay:
+ mSaveRec.addYearlyDay( mYearly->day() );
+ break;
+ }
+ }
+
+ if ( duration > 0 ) {
+ mSaveRec.setDuration( duration );
+ } else if ( duration == 0 ) {
+ mSaveRec.setEndDate( endDate );
+ }
+
+ mSaveRec.setExDates( mExceptions->dates() );
+}
-KOEditorRecurrenceDialog::KOEditorRecurrenceDialog(TQWidget * parent) :
- KDialogBase( parent, 0, false, i18n("Recurrence"), Ok )
+void KOEditorRecurrence::restoreValues()
+{
+ TQBitArray rDays( 7 );
+ int day = 0;
+ int count = 0;
+ int month = 0;
+
+ if ( mSaveRec.startDateTime().isValid() && mSaveRec.endDateTime().isValid() ) {
+ setDefaults( mSaveRec.startDateTime(), mSaveRec.endDateTime(), mSaveRec.doesFloat() );
+ }
+
+ int recurrenceType;
+ switch ( mSaveRec.recurrenceType() ) {
+ case Recurrence::rNone:
+ recurrenceType = RecurrenceChooser::Weekly;
+ break;
+
+ case Recurrence::rDaily:
+ recurrenceType = RecurrenceChooser::Daily;
+ mDaily->setFrequency( mSaveRec.frequency() );
+ break;
+
+ case Recurrence::rWeekly:
+ recurrenceType = RecurrenceChooser::Weekly;
+
+ mWeekly->setFrequency( mSaveRec.frequency() );
+ mWeekly->setDays( mSaveRec.days() );
+ break;
+
+ case Recurrence::rMonthlyPos:
+ {
+ // TODO: 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;
+
+ TQValueList<RecurrenceRule::WDayPos> rmp = mSaveRec.monthPositions();
+ if ( !rmp.isEmpty() ) {
+ mMonthly->setByPos( rmp.first().pos(), rmp.first().day() );
+ }
+ mMonthly->setFrequency( mSaveRec.frequency() );
+ break;
+ }
+
+ case Recurrence::rMonthlyDay:
+ {
+ recurrenceType = RecurrenceChooser::Monthly;
+
+ TQValueList<int> rmd = mSaveRec.monthDays();
+ // check if we have any setting for which day (vcs import is broken and
+ // does not set any day, thus we need to check)
+ if ( !rmd.isEmpty() ) {
+ day = rmd.first();
+ }
+ if ( day > 0 ) {
+ mMonthly->setByDay( day );
+ mMonthly->setFrequency( mSaveRec.frequency() );
+ }
+ break;
+ }
+
+ case Recurrence::rYearlyMonth:
+ {
+ recurrenceType = RecurrenceChooser::Yearly;
+
+ TQValueList<int> rmd = mSaveRec.yearDates();
+ if ( !rmd.isEmpty() ) {
+ day = rmd.first();
+ }
+ rmd = mSaveRec.yearMonths();
+ if ( !rmd.isEmpty() ) {
+ month = rmd.first();
+ }
+ if ( day > 0 && month > 0 ) {
+ mYearly->setByMonth( day, month );
+ mYearly->setFrequency( mSaveRec.frequency() );
+ }
+ break;
+ }
+
+ case Recurrence::rYearlyPos:
+ {
+ recurrenceType = RecurrenceChooser::Yearly;
+
+ TQValueList<int> months = mSaveRec.yearMonths();
+ if ( !months.isEmpty() ) {
+ month = months.first();
+ }
+ TQValueList<RecurrenceRule::WDayPos> pos = mSaveRec.yearPositions();
+ if ( !pos.isEmpty() ) {
+ count = pos.first().pos();
+ day = pos.first().day();
+ }
+ if ( count > 0 && day > 0 && month > 0 ) {
+ mYearly->setByPos( count, day, month );
+ mYearly->setFrequency( mSaveRec.frequency() );
+ }
+ break;
+ }
+
+ case Recurrence::rYearlyDay:
+ {
+ recurrenceType = RecurrenceChooser::Yearly;
+
+ TQValueList<int> days = mSaveRec.yearDays();
+ if ( !days.isEmpty() ) {
+ day = days.first();
+ }
+ if ( day > 0 ) {
+ mYearly->setByDay( day );
+ mYearly->setFrequency( mSaveRec.frequency() );
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ mRecurrenceChooser->setType( recurrenceType );
+ showCurrentRule( recurrenceType );
+
+ if ( mSaveRec.startDateTime().isValid() ) {
+ mRecurrenceRange->setDateTimes( mSaveRec.startDateTime() );
+ }
+
+ mRecurrenceRange->setDuration( mSaveRec.duration() );
+ if ( mSaveRec.duration() == 0 && mSaveRec.endDate().isValid() ) {
+ mRecurrenceRange->setEndDate( mSaveRec.endDate() );
+ }
+
+ mExceptions->setDates( mSaveRec.exDates() );
+}
+
+KOEditorRecurrenceDialog::KOEditorRecurrenceDialog(TQWidget * parent)
+ : KDialogBase( parent, 0, false, i18n("Recurrence"), Ok|Cancel ), mRecurEnabled( false )
{
mRecurrence = new KOEditorRecurrence( this );
setMainWidget( mRecurrence );
}
+
+void KOEditorRecurrenceDialog::slotOk()
+{
+ mRecurEnabled = mRecurrence->doesRecur();
+ mRecurrence->saveValues();
+ emit okClicked(); // tell the incidence editor to update the recurrenceString
+ accept();
+}
+
+void KOEditorRecurrenceDialog::slotCancel()
+{
+ mRecurrence->setRecurrenceEnabled( mRecurEnabled );
+ mRecurrence->restoreValues();
+ reject();
+}
diff --git a/korganizer/koeditorrecurrence.h b/korganizer/koeditorrecurrence.h
index 0ce9c6dd..05074cdd 100644
--- a/korganizer/koeditorrecurrence.h
+++ b/korganizer/koeditorrecurrence.h
@@ -297,6 +297,9 @@ class KOEditorRecurrence : public QWidget
bool doesRecur();
+ void saveValues();
+ void restoreValues();
+
public slots:
void setRecurrenceEnabled( bool );
void setDateTimes( const TQDateTime &start, const TQDateTime &end );
@@ -311,6 +314,7 @@ class KOEditorRecurrence : public QWidget
void showRecurrenceRangeDialog();
private:
+ Recurrence mSaveRec;
TQCheckBox *mEnabledCheck;
TQGroupBox *mTimeGroupBox;
@@ -345,8 +349,13 @@ class KOEditorRecurrenceDialog : public KDialogBase
KOEditorRecurrenceDialog( TQWidget *parent );
KOEditorRecurrence* editor() const { return mRecurrence; }
+ protected slots:
+ void slotOk();
+ void slotCancel();
+
private:
KOEditorRecurrence *mRecurrence;
+ bool mRecurEnabled;
};
#endif
diff --git a/korganizer/koeventeditor.cpp b/korganizer/koeventeditor.cpp
index 5cc7041e..8a8340fc 100644
--- a/korganizer/koeventeditor.cpp
+++ b/korganizer/koeventeditor.cpp
@@ -41,7 +41,6 @@
#include "koprefs.h"
#include "koeditorgeneralevent.h"
-#include "koeditoralarms.h"
#include "koeditorrecurrence.h"
#include "koeditordetails.h"
#include "koeditorfreebusy.h"
@@ -66,7 +65,6 @@ KOEventEditor::~KOEventEditor()
void KOEventEditor::init()
{
setupGeneral();
-// setupAlarmsTab();
setupRecurrence();
setupFreeBusy();
setupDesignerTabs( "event" );
@@ -111,7 +109,9 @@ void KOEventEditor::reload()
{
kdDebug(5850) << "KOEventEditor::reload()" << endl;
- if ( mEvent ) readEvent( mEvent, mCalendar );
+ if ( mEvent ) {
+ readEvent( mEvent, mCalendar, TQDate() );
+ }
}
void KOEventEditor::setupGeneral()
@@ -129,9 +129,6 @@ void KOEventEditor::setupGeneral()
mGeneral->initHeader( topFrame, topLayout );
mGeneral->initTime(topFrame,topLayout);
-// TQBoxLayout *alarmLineLayout = new TQHBoxLayout(topLayout);
- mGeneral->initAlarm(topFrame,topLayout);
- mGeneral->enableAlarm( false );
topLayout->addStretch( 1 );
@@ -166,27 +163,15 @@ void KOEventEditor::setupGeneral()
mGeneral->finishSetup();
}
-void KOEventEditor::modified (int /*modification*/)
+void KOEventEditor::modified()
{
- // Play dump, just reload the event. This dialog has become so complicated
+ // Play dumb, just reload the event. This dialog has become so complicated
// that there is no point in trying to be smart here...
reload();
}
void KOEventEditor::setupRecurrence()
{
-#if 0
- TQFrame *topFrame = addPage( i18n("Rec&urrence") );
-
- TQWhatsThis::add( topFrame,
- i18n("The Recurrence tab allows you to set options on "
- "how often this event recurs.") );
-
- TQBoxLayout *topLayout = new TQVBoxLayout( topFrame );
-
- mRecurrence = new KOEditorRecurrence( topFrame );
- topLayout->addWidget( mRecurrence );
-#endif
mRecurrenceDialog = new KOEditorRecurrenceDialog( this );
mRecurrenceDialog->hide();
mRecurrence = mRecurrenceDialog->editor();
@@ -205,7 +190,9 @@ void KOEventEditor::setupFreeBusy()
topLayout->addWidget( mFreeBusy );
}
-void KOEventEditor::editIncidence( Incidence *incidence, Calendar *calendar )
+void KOEventEditor::editIncidence( Incidence *incidence,
+ const TQDate &date,
+ Calendar *calendar )
{
Event*event = dynamic_cast<Event*>(incidence);
if ( event ) {
@@ -213,7 +200,9 @@ void KOEventEditor::editIncidence( Incidence *incidence, Calendar *calendar )
mEvent = event;
mCalendar = calendar;
- readEvent( mEvent, mCalendar );
+
+ const TQDate &dt = mRecurIncidence && date.isValid() ? date : incidence->dtStart().date();
+ readEvent( mEvent, mCalendar, dt );
}
setCaption( i18n("Edit Event") );
@@ -263,9 +252,12 @@ void KOEventEditor::loadDefaults()
bool KOEventEditor::processInput()
{
- kdDebug(5850) << "KOEventEditor::processInput()" << endl;
+ kdDebug(5850) << "KOEventEditor::processInput(); event is " << mEvent << endl;
- if ( !validateInput() || !mChanger ) return false;
+ if ( !validateInput() || !mChanger ) {
+ kdDebug(5850) << " mChanger is " << mChanger << endl;
+ return false;
+ }
TQGuardedPtr<KOEditorFreeBusy> freeBusy( mFreeBusy );
@@ -280,11 +272,12 @@ bool KOEventEditor::processInput()
if( *event == *mEvent ) {
// Don't do anything
- kdDebug(5850) << "Event not changed\n";
- if ( mIsCounter )
+ kdDebug(5850) << "Event not changed" << endl;
+ if ( mIsCounter ) {
KMessageBox::information( this, i18n("You didn't change the event, thus no counter proposal has been sent to the organizer."), i18n("No changes") );
+ }
} else {
- kdDebug(5850) << "Event changed\n";
+ kdDebug(5850) << "Event changed" << endl;
//IncidenceChanger::assignIncidence( mEvent, event );
writeEvent( mEvent );
if ( mIsCounter ) {
@@ -293,9 +286,17 @@ bool KOEventEditor::processInput()
Event *event = mEvent->clone();
event->clearAttendees();
event->setSummary( i18n("My counter proposal for: %1").arg( mEvent->summary() ) );
- mChanger->addIncidence( event );
+ mChanger->addIncidence( event, mResource, mSubResource, this );
} else {
- mChanger->changeIncidence( oldEvent, mEvent );
+ if ( mRecurIncidence && mRecurIncidenceAfterDissoc ) {
+ mChanger->addIncidence( mEvent, mResource, mSubResource, this );
+
+ mChanger->changeIncidence( mRecurIncidence, mRecurIncidenceAfterDissoc,
+ KOGlobals::RECURRENCE_MODIFIED_ALL_FUTURE, this );
+
+ } else {
+ mChanger->changeIncidence( oldEvent, mEvent, KOGlobals::NOTHING_MODIFIED, this );
+ }
}
}
delete event;
@@ -307,14 +308,16 @@ bool KOEventEditor::processInput()
KOPrefs::instance()->email() ) );
writeEvent( mEvent );
// NOTE: triggered by addIncidence, the kolab resource might open a non-modal dialog (parent is not available in the resource) to select a resource folder. Thus the user can close this dialog before addIncidence() returns.
- if ( !mChanger->addIncidence( mEvent, this ) ) {
+ if ( !mChanger->addIncidence( mEvent, mResource, mSubResource, this ) ) {
delete mEvent;
mEvent = 0;
return false;
}
}
// if "this" was deleted, freeBusy is 0 (being a guardedptr)
- if ( freeBusy ) freeBusy->cancelReload();
+ if ( freeBusy ) {
+ freeBusy->cancelReload();
+ }
return true;
}
@@ -324,6 +327,11 @@ void KOEventEditor::processCancel()
kdDebug(5850) << "KOEventEditor::processCancel()" << endl;
if ( mFreeBusy ) mFreeBusy->cancelReload();
+
+ if ( mRecurIncidence && mRecurIncidenceAfterDissoc ) {
+ *mRecurIncidenceAfterDissoc = *mRecurIncidence;
+ }
+
}
void KOEventEditor::deleteEvent()
@@ -336,11 +344,11 @@ void KOEventEditor::deleteEvent()
reject();
}
-void KOEventEditor::readEvent( Event *event, Calendar *calendar, bool tmpl )
+void KOEventEditor::readEvent( Event *event, Calendar *calendar, const TQDate &date, bool tmpl )
{
- mGeneral->readEvent( event, calendar, tmpl );
+ mGeneral->readEvent( event, calendar, date, tmpl );
mRecurrence->readIncidence( event );
-// mAlarms->readIncidence( event );
+
if ( mFreeBusy ) {
mFreeBusy->readEvent( event );
mFreeBusy->triggerReload();
@@ -368,11 +376,14 @@ void KOEventEditor::writeEvent( Event *event )
bool KOEventEditor::validateInput()
{
- if ( !mGeneral->validateInput() ) return false;
- if ( !mDetails->validateInput() ) return false;
- if ( !mRecurrence->validateInput() ) return false;
-
- return true;
+ if ( !mGeneral->validateInput() ||
+ !mDetails->validateInput() ||
+ !mRecurrence->validateInput() ) {
+ kdDebug(5850) << "ValidateInput returns false" << endl;
+ return false;
+ } else {
+ return true;
+ }
}
int KOEventEditor::msgItemDelete()
@@ -390,7 +401,7 @@ void KOEventEditor::loadTemplate( /*const*/ CalendarLocal& cal )
i18n("Template does not contain a valid event.") );
} else {
kdDebug(5850) << "KOEventEditor::slotLoadTemplate(): readTemplate" << endl;
- readEvent( events.first(), 0, true );
+ readEvent( events.first(), 0, TQDate(), true );
}
}
@@ -414,9 +425,9 @@ TQObject *KOEventEditor::typeAheadReceiver() const
void KOEventEditor::updateRecurrenceSummary()
{
- Event *ev = new Event();
+ Event *ev = new Event();
writeEvent( ev );
- mGeneral->updateRecurrenceSummary( IncidenceFormatter::recurrenceString( ev ) );
+ mGeneral->updateRecurrenceSummary( ev );
delete ev;
}
diff --git a/korganizer/koeventeditor.h b/korganizer/koeventeditor.h
index ba097479..dbcec875 100644
--- a/korganizer/koeventeditor.h
+++ b/korganizer/koeventeditor.h
@@ -57,7 +57,7 @@ class KOEventEditor : public KOIncidenceEditor
void init();
/** This event has been modified externally */
- void modified (int change=0);
+ void modified();
void reload();
/**
@@ -74,7 +74,7 @@ class KOEventEditor : public KOIncidenceEditor
/**
Edit an existing event.
*/
- void editIncidence( Incidence *incidence, Calendar *calendar );
+ void editIncidence( Incidence *incidence, const TQDate &date, Calendar *calendar );
/**
Set widgets to the given date/time values
@@ -85,7 +85,7 @@ class KOEventEditor : public KOIncidenceEditor
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 *event, Calendar *calendar, bool tmpl = false );
+ void readEvent( Event *event, Calendar *calendar, const TQDate &date, bool tmpl = false );
/**
Write event settings to event object
*/
diff --git a/korganizer/koeventpopupmenu.cpp b/korganizer/koeventpopupmenu.cpp
index 75c96d20..b0326ee5 100644
--- a/korganizer/koeventpopupmenu.cpp
+++ b/korganizer/koeventpopupmenu.cpp
@@ -45,6 +45,7 @@
KOEventPopupMenu::KOEventPopupMenu()
{
+ mCalendar = 0;
mCurrentIncidence = 0;
mCurrentDate = TQDate();
mHasAdditionalItems = false;
@@ -89,8 +90,9 @@ KOEventPopupMenu::KOEventPopupMenu()
this, TQT_SLOT(forward()) );
}
-void KOEventPopupMenu::showIncidencePopup( Incidence *incidence, const TQDate &qd )
+void KOEventPopupMenu::showIncidencePopup( Calendar *cal, Incidence *incidence, const TQDate &qd )
{
+ mCalendar = cal;
mCurrentIncidence = incidence;
mCurrentDate = qd;
@@ -123,19 +125,23 @@ void KOEventPopupMenu::addAdditionalItem(const TQIconSet &icon,const TQString &t
void KOEventPopupMenu::popupShow()
{
- if (mCurrentIncidence) emit showIncidenceSignal(mCurrentIncidence);
+ if ( mCurrentIncidence ) {
+ emit showIncidenceSignal( mCurrentIncidence, mCurrentDate );
+ }
}
void KOEventPopupMenu::popupEdit()
{
- if (mCurrentIncidence) emit editIncidenceSignal(mCurrentIncidence);
+ if ( mCurrentIncidence ) {
+ emit editIncidenceSignal( mCurrentIncidence, mCurrentDate );
+ }
}
void KOEventPopupMenu::print()
{
#ifndef KORG_NOPRINTER
KOCoreHelper helper;
- CalPrinter printer( this, 0, &helper );
+ CalPrinter printer( this, mCalendar, &helper );
connect( this, TQT_SIGNAL(configChanged()), &printer, TQT_SLOT(updateConfig()) );
Incidence::List selectedIncidences;
diff --git a/korganizer/koeventpopupmenu.h b/korganizer/koeventpopupmenu.h
index 8d4f2df2..96911b8c 100644
--- a/korganizer/koeventpopupmenu.h
+++ b/korganizer/koeventpopupmenu.h
@@ -31,6 +31,7 @@
#include <tqdatetime.h>
namespace KCal {
+class Calendar;
class Incidence;
}
using namespace KCal;
@@ -46,7 +47,7 @@ class KOEventPopupMenu : public TQPopupMenu {
public slots:
- void showIncidencePopup( Incidence *, const TQDate & );
+ void showIncidencePopup( Calendar *, Incidence *, const TQDate & );
protected slots:
void popupShow();
@@ -62,17 +63,19 @@ class KOEventPopupMenu : public TQPopupMenu {
void forward();
signals:
- void editIncidenceSignal(Incidence *);
- void showIncidenceSignal(Incidence *);
- void deleteIncidenceSignal(Incidence *);
- void cutIncidenceSignal(Incidence *);
- void copyIncidenceSignal(Incidence *);
+ void configChanged();
+ void editIncidenceSignal( Incidence *, const TQDate & );
+ void showIncidenceSignal( Incidence *, const TQDate & );
+ void deleteIncidenceSignal( Incidence * );
+ void cutIncidenceSignal( Incidence * );
+ void copyIncidenceSignal( Incidence * );
void pasteIncidenceSignal();
- void toggleAlarmSignal(Incidence *);
+ void toggleAlarmSignal( Incidence * );
void dissociateOccurrenceSignal( Incidence *, const TQDate & );
void dissociateFutureOccurrenceSignal( Incidence *, const TQDate & );
private:
+ Calendar *mCalendar;
Incidence *mCurrentIncidence;
TQDate mCurrentDate;
diff --git a/korganizer/koeventview.cpp b/korganizer/koeventview.cpp
index 17708953..9e01ea4e 100644
--- a/korganizer/koeventview.cpp
+++ b/korganizer/koeventview.cpp
@@ -60,25 +60,25 @@ KOEventView::~KOEventView()
KOEventPopupMenu *KOEventView::eventPopup()
{
KOEventPopupMenu *eventPopup = new KOEventPopupMenu;
-
- connect(eventPopup,TQT_SIGNAL(editIncidenceSignal(Incidence *)),
- TQT_SIGNAL(editIncidenceSignal(Incidence *)));
- connect(eventPopup,TQT_SIGNAL(showIncidenceSignal(Incidence *)),
- TQT_SIGNAL(showIncidenceSignal(Incidence *)));
- connect(eventPopup,TQT_SIGNAL(deleteIncidenceSignal(Incidence *)),
- TQT_SIGNAL(deleteIncidenceSignal(Incidence *)));
- connect(eventPopup,TQT_SIGNAL(cutIncidenceSignal(Incidence *)),
- TQT_SIGNAL(cutIncidenceSignal(Incidence *)));
- connect(eventPopup,TQT_SIGNAL(copyIncidenceSignal(Incidence *)),
- TQT_SIGNAL(copyIncidenceSignal(Incidence *)));
- connect(eventPopup,TQT_SIGNAL(pasteIncidenceSignal()),
- TQT_SIGNAL(pasteIncidenceSignal()));
- connect(eventPopup,TQT_SIGNAL(toggleAlarmSignal(Incidence *)),
- TQT_SIGNAL(toggleAlarmSignal(Incidence*)));
- connect(eventPopup,TQT_SIGNAL(dissociateOccurrenceSignal( Incidence *, const TQDate & )),
- TQT_SIGNAL(dissociateOccurrenceSignal( Incidence *, const TQDate & )));
- connect(eventPopup,TQT_SIGNAL(dissociateFutureOccurrenceSignal( Incidence *, const TQDate & )),
- TQT_SIGNAL(dissociateFutureOccurrenceSignal( Incidence *, const TQDate & )));
+
+ connect( eventPopup, TQT_SIGNAL(editIncidenceSignal(Incidence *,const TQDate &)),
+ TQT_SIGNAL(editIncidenceSignal(Incidence *,const TQDate &)) );
+ connect( eventPopup, TQT_SIGNAL(showIncidenceSignal(Incidence *,const TQDate &)),
+ TQT_SIGNAL(showIncidenceSignal(Incidence *,const TQDate &)) );
+ connect( eventPopup, TQT_SIGNAL(deleteIncidenceSignal(Incidence *)),
+ TQT_SIGNAL(deleteIncidenceSignal(Incidence *)) );
+ connect( eventPopup, TQT_SIGNAL(cutIncidenceSignal(Incidence *)),
+ TQT_SIGNAL(cutIncidenceSignal(Incidence *)) );
+ connect( eventPopup, TQT_SIGNAL(copyIncidenceSignal(Incidence *)),
+ TQT_SIGNAL(copyIncidenceSignal(Incidence *)) );
+ connect( eventPopup, TQT_SIGNAL(pasteIncidenceSignal()),
+ TQT_SIGNAL(pasteIncidenceSignal()) );
+ connect( eventPopup, TQT_SIGNAL(toggleAlarmSignal(Incidence *)),
+ TQT_SIGNAL(toggleAlarmSignal(Incidence*)) );
+ connect( eventPopup, TQT_SIGNAL(dissociateOccurrenceSignal(Incidence *,const TQDate &)),
+ TQT_SIGNAL(dissociateOccurrenceSignal(Incidence *,const TQDate &)) );
+ connect( eventPopup, TQT_SIGNAL(dissociateFutureOccurrenceSignal(Incidence *,const TQDate &)),
+ TQT_SIGNAL(dissociateFutureOccurrenceSignal(Incidence *,const TQDate &)) );
return eventPopup;
}
@@ -102,14 +102,14 @@ TQPopupMenu *KOEventView::newEventPopup()
void KOEventView::popupShow()
{
- emit showIncidenceSignal(mCurrentIncidence);
+ emit showIncidenceSignal(mCurrentIncidence, TQDate() );
}
//---------------------------------------------------------------------------
void KOEventView::popupEdit()
{
- emit editIncidenceSignal(mCurrentIncidence);
+ emit editIncidenceSignal( mCurrentIncidence, TQDate() );
}
//---------------------------------------------------------------------------
@@ -137,14 +137,16 @@ void KOEventView::popupCopy()
void KOEventView::showNewEventPopup()
{
- TQPopupMenu *popup = newEventPopup();
- if ( !popup ) {
- kdError() << "KOEventView::showNewEventPopup(): popup creation failed"
- << endl;
- return;
+ if ( !readOnly() ) {
+ TQPopupMenu *popup = newEventPopup();
+ if ( !popup ) {
+ kdError() << "KOEventView::showNewEventPopup(): popup creation failed"
+ << endl;
+ return;
+ }
+
+ popup->popup( TQCursor::pos() );
}
-
- popup->popup( TQCursor::pos() );
}
//---------------------------------------------------------------------------
@@ -157,10 +159,11 @@ void KOEventView::defaultAction( Incidence *incidence )
kdDebug(5850) << " type: " << incidence->type() << endl;
- if ( incidence->isReadOnly() )
- emit showIncidenceSignal(incidence);
- else
- emit editIncidenceSignal(incidence);
+ if ( incidence->isReadOnly() ) {
+ emit showIncidenceSignal( incidence, TQDate() );
+ } else {
+ emit editIncidenceSignal( incidence, TQDate() );
+ }
}
//---------------------------------------------------------------------------
diff --git a/korganizer/koeventview.h b/korganizer/koeventview.h
index c3334881..69f6377f 100644
--- a/korganizer/koeventview.h
+++ b/korganizer/koeventview.h
@@ -90,6 +90,8 @@ class KOEventView : public KOrg::BaseView
/** This view is an view for displaying events. */
bool isEventView() { return true; }
+ bool supportsDateNavigation() const { return true; }
+
public slots:
/**
@@ -126,6 +128,7 @@ class KOEventView : public KOrg::BaseView
protected:
Incidence *mCurrentIncidence; // Incidence selected e.g. for a context menu
+
};
#endif
diff --git a/korganizer/koeventviewer.cpp b/korganizer/koeventviewer.cpp
index 47ac5b7a..83534d6a 100644
--- a/korganizer/koeventviewer.cpp
+++ b/korganizer/koeventviewer.cpp
@@ -23,24 +23,62 @@
*/
#include "koeventviewer.h"
-
+#include "koglobals.h"
#include "urihandler.h"
+#include <libkcal/attachmenthandler.h>
+#include <libkcal/calendar.h>
#include <libkcal/incidence.h>
#include <libkcal/incidenceformatter.h>
+
#include <kdebug.h>
-#include <koglobals.h>
+#include <klocale.h>
+#include <kpopupmenu.h>
+
+#include <tqcursor.h>
+#include <tqregexp.h>
+#include <tqtooltip.h>
-KOEventViewer::KOEventViewer( TQWidget *parent, const char *name )
- : TQTextBrowser( parent, name ), mDefaultText("")
+KOEventViewer::KOEventViewer( Calendar *calendar, TQWidget *parent, const char *name )
+ : TQTextBrowser( parent, name ), mCalendar( calendar ), mDefaultText("")
{
mIncidence = 0;
+ connect( this, TQT_SIGNAL(highlighted(const TQString &)), TQT_SLOT(message(const TQString &)) );
}
KOEventViewer::~KOEventViewer()
{
}
+void KOEventViewer::message( const TQString &link )
+{
+ mAttachLink = TQString();
+ if ( link.isEmpty() ) {
+ TQToolTip::remove( this );
+ return;
+ }
+
+ TQString ttStr;
+ if ( link.startsWith( "kmail:" ) ) {
+ ttStr = i18n( "Open the message in KMail" );
+ } else if ( link.startsWith( "mailto:" ) ) {
+ ttStr = i18n( "Send an email message to %1" ).arg( link.mid( 7 ) );
+ } else if ( link.startsWith( "uid:" ) ) {
+ ttStr = i18n( "Lookup the contact in KAddressbook" );
+ } else if ( link.startsWith( "ATTACH:" ) ) {
+ TQString tmp = link;
+ tmp.remove( TQRegExp( "^ATTACH://" ) );
+ TQString uid = tmp.section( ':', 0, 0 );
+ TQString name = tmp.section( ':', -1, -1 );
+ ttStr = i18n( "View attachment \"%1\"" ).arg( name );
+ mAttachLink = link;
+ } else { // no special URI, let KDE handle it
+ ttStr = i18n( "Launch a viewer on the link" );
+ }
+
+ TQToolTip::add( this, ttStr );
+}
+
void KOEventViewer::readSettings( KConfig * config )
{
if ( config ) {
@@ -50,7 +88,7 @@ void KOEventViewer::readSettings( KConfig * config )
config->setGroup( TQString("EventViewer-%1").arg( name() ) );
int zoomFactor = config->readNumEntry("ZoomFactor", pointSize() );
zoomTo( zoomFactor/2 );
- kdDebug(5850) << " KOEventViewer: restoring the pointSize: "<< pointSize()
+ kdDebug(5850) << " KOEventViewer: restoring the pointSize: "<< pointSize()
<< ", zoomFactor: " << zoomFactor << endl;
#endif
}
@@ -67,20 +105,25 @@ void KOEventViewer::writeSettings( KConfig * config )
void KOEventViewer::setSource( const TQString &n )
{
- UriHandler::process( n );
+ UriHandler::process( parentWidget(), n );
}
-bool KOEventViewer::appendIncidence( Incidence *incidence )
+bool KOEventViewer::appendIncidence( Incidence *incidence, const TQDate &date )
{
- addText( IncidenceFormatter::extensiveDisplayString( incidence ) );
+ addText( IncidenceFormatter::extensiveDisplayStr( mCalendar, incidence, date ) );
return true;
}
-void KOEventViewer::setIncidence( Incidence *incidence )
+void KOEventViewer::setCalendar( Calendar *calendar )
+{
+ mCalendar = calendar;
+}
+
+void KOEventViewer::setIncidence( Incidence *incidence, const TQDate &date )
{
clearEvents();
if( incidence ) {
- appendIncidence( incidence );
+ appendIncidence( incidence, date );
mIncidence = incidence;
} else {
clearEvents( true );
@@ -105,20 +148,43 @@ void KOEventViewer::setDefaultText( const TQString &text )
mDefaultText = text;
}
-void KOEventViewer::changeIncidenceDisplay( Incidence *incidence, int action )
+void KOEventViewer::changeIncidenceDisplay( Incidence *incidence, const TQDate &date, int action )
{
if ( mIncidence && ( incidence->uid() == mIncidence->uid() ) ) {
- switch (action ) {
- case KOGlobals::INCIDENCEEDITED:{
- setIncidence( incidence );
- break;
- }
- case KOGlobals::INCIDENCEDELETED: {
- setIncidence( 0 );
- break;
- }
+ switch ( action ) {
+ case KOGlobals::INCIDENCEEDITED:
+ setIncidence( incidence, date );
+ break;
+ case KOGlobals::INCIDENCEDELETED:
+ setIncidence( 0, date );
+ break;
}
}
}
+void KOEventViewer::contentsContextMenuEvent( TQContextMenuEvent *e )
+{
+ TQString name = UriHandler::attachmentNameFromUri( mAttachLink );
+ TQString uid = UriHandler::uidFromUri( mAttachLink );
+ if ( name.isEmpty() || uid.isEmpty() ) {
+ TQTextBrowser::contentsContextMenuEvent( e );
+ return;
+ }
+
+ KPopupMenu *menu = new KPopupMenu();
+ menu->insertItem( i18n( "Open Attachment" ), 0 );
+ menu->insertItem( i18n( "Save Attachment As..." ), 1 );
+
+ switch( menu->exec( TQCursor::pos(), 0 ) ) {
+ case 0: // open
+ AttachmentHandler::view( parentWidget(), name, uid );
+ break;
+ case 1: // save as
+ AttachmentHandler::saveAs( parentWidget(), name, uid );
+ break;
+ default:
+ break;
+ }
+}
+
#include "koeventviewer.moc"
diff --git a/korganizer/koeventviewer.h b/korganizer/koeventviewer.h
index 80b1ef77..c4022d02 100644
--- a/korganizer/koeventviewer.h
+++ b/korganizer/koeventviewer.h
@@ -24,15 +24,13 @@
#ifndef KOEVENTVIEWER_H
#define KOEVENTVIEWER_H
-#include <tqtextbrowser.h>
#include <kdepimmacros.h>
-
#include <kconfig.h>
+#include <tqtextbrowser.h>
+
namespace KCal {
-class Incidence;
-class Todo;
-class Event;
-class Journal;
+ class Calendar;
+ class Incidence;
}
using namespace KCal;
@@ -41,18 +39,23 @@ using namespace KCal;
*/
class KDE_EXPORT KOEventViewer : public QTextBrowser
{
- Q_OBJECT
+ Q_OBJECT
public:
- KOEventViewer( TQWidget *parent = 0, const char *name = 0 );
+ explicit KOEventViewer( Calendar *calendar, TQWidget *parent = 0, const char *name = 0 );
virtual ~KOEventViewer();
/**
Reimplemented from TQTextBrowser to handle links.
*/
void setSource( const TQString & );
-
- virtual bool appendIncidence( Incidence * );
-
+
+ virtual bool appendIncidence( Incidence *incidence, const TQDate &date );
+
+ /**
+ Set the Calendar associated with this viewer.
+ */
+ void setCalendar ( Calendar *calendar );
+
/**
Clear viewer. If \a now is set to true delete view immediately. If set to
false delete it with next call to appendIncidence().
@@ -61,30 +64,35 @@ class KDE_EXPORT KOEventViewer : public QTextBrowser
/**
Add given text to currently shown content.
- */
-
+ */
+
void addText( const TQString &text );
-
+
/**
- Set the default text that is showed when
+ Set the default text that is showed when
there aren't a incidence to show
*/
void setDefaultText( const TQString &text );
-
- void readSettings( KConfig *config);
- void writeSettings ( KConfig *config);
-
+
+ void readSettings( KConfig *config );
+ void writeSettings ( KConfig *config );
+
public slots:
/**
Show given incidence in viewer. Clear all previously shown incidences.
*/
- virtual void setIncidence( Incidence * );
- void changeIncidenceDisplay( Incidence *incidence, int action );
+ void setIncidence( Incidence *incidence, const TQDate &date );
+ void changeIncidenceDisplay( Incidence *incidence, const TQDate &date, int action );
+ void message( const TQString &link );
+ void contentsContextMenuEvent( TQContextMenuEvent * );
+
private:
+ Calendar *mCalendar;
Incidence *mIncidence;
TQTextBrowser *mEventTextView;
TQString mDefaultText;
TQString mText;
+ TQString mAttachLink;
};
#endif
diff --git a/korganizer/koeventviewerdialog.cpp b/korganizer/koeventviewerdialog.cpp
index a51e5bcc..d88aa31c 100644
--- a/korganizer/koeventviewerdialog.cpp
+++ b/korganizer/koeventviewerdialog.cpp
@@ -28,21 +28,20 @@
#include <klocale.h>
-KOEventViewerDialog::KOEventViewerDialog( TQWidget *parent, const char *name,
- bool compact )
+KOEventViewerDialog::KOEventViewerDialog( Calendar *calendar, TQWidget *parent,
+ const char *name, bool compact )
: KDialogBase( parent, name, false, i18n("Event Viewer"), Ok, Ok, false,
i18n("Edit") )
{
- mEventViewer = new KOEventViewer( this );
+ mEventViewer = new KOEventViewer( calendar, this );
setMainWidget( mEventViewer );
- // FIXME: Set a sensible size (based on the content?).
if ( compact ) {
setFixedSize( 240,284 );
move( 0, 15 );
} else {
- setMinimumSize( 300, 200 );
- resize( 320, 300 );
+ setMinimumSize( 500, 500 );
+ resize( 520, 500 );
}
connect( this, TQT_SIGNAL(finished()), this, TQT_SLOT(delayedDestruct()) );
}
@@ -51,9 +50,14 @@ KOEventViewerDialog::~KOEventViewerDialog()
{
}
+void KOEventViewerDialog::setCalendar( Calendar *calendar )
+{
+ mEventViewer->setCalendar( calendar );
+}
+
void KOEventViewerDialog::addText( const TQString &text )
{
- mEventViewer->addText(text);
+ mEventViewer->addText( text );
}
#include "koeventviewerdialog.moc"
diff --git a/korganizer/koeventviewerdialog.h b/korganizer/koeventviewerdialog.h
index e14c6baf..dc0ceb7b 100644
--- a/korganizer/koeventviewerdialog.h
+++ b/korganizer/koeventviewerdialog.h
@@ -42,13 +42,20 @@ class KDE_EXPORT KOEventViewerDialog : public KDialogBase
{
Q_OBJECT
public:
- KOEventViewerDialog( TQWidget *parent = 0, const char *name = 0,
- bool compact = false );
+ explicit KOEventViewerDialog( Calendar *calendar, TQWidget *parent = 0,
+ const char *name = 0, bool compact = false );
virtual ~KOEventViewerDialog();
- void setIncidence( Incidence *incidence ) { mEventViewer->setIncidence( incidence ); }
- void appendIncidence( Incidence *incidence ) { mEventViewer->appendIncidence( incidence ); }
+ void setIncidence( Incidence *incidence, const TQDate &date )
+ {
+ mEventViewer->setIncidence( incidence, date );
+ }
+ void appendIncidence( Incidence *incidence, const TQDate &date )
+ {
+ mEventViewer->appendIncidence( incidence, date );
+ }
+ void setCalendar( Calendar *calendar );
void addText( const TQString &text );
private:
diff --git a/korganizer/koglobals.h b/korganizer/koglobals.h
index 77158810..119eb6c1 100644
--- a/korganizer/koglobals.h
+++ b/korganizer/koglobals.h
@@ -24,7 +24,9 @@
#define KORG_GLOBALS_H
#include <kdepimmacros.h>
+#include <tqwidget.h>
+class TQDate;
class TQPixmap;
class TQIconSet;
class KCalendarSystem;
@@ -39,11 +41,40 @@ class KDE_EXPORT KOGlobals
public:
static KOGlobals *self();
- enum { INCIDENCEADDED, INCIDENCEEDITED, INCIDENCEDELETED };
- enum { PRIORITY_MODIFIED, COMPLETION_MODIFIED, CATEGORY_MODIFIED,
- DATE_MODIFIED, RELATION_MODIFIED, ALARM_MODIFIED,
- DESCRIPTION_MODIFIED, SUMMARY_MODIFIED,
- COMPLETION_MODIFIED_WITH_RECURRENCE, UNKNOWN_MODIFIED };
+ enum HowChanged {
+ INCIDENCEADDED,
+ INCIDENCEEDITED,
+ INCIDENCEDELETED,
+ NOCHANGE
+ };
+ enum WhatChanged {
+ PRIORITY_MODIFIED,
+ COMPLETION_MODIFIED,
+ CATEGORY_MODIFIED,
+ DATE_MODIFIED,
+ RELATION_MODIFIED,
+ ALARM_MODIFIED,
+ DESCRIPTION_MODIFIED,
+ SUMMARY_MODIFIED,
+ COMPLETION_MODIFIED_WITH_RECURRENCE,
+ RECURRENCE_MODIFIED_ONE_ONLY,
+ RECURRENCE_MODIFIED_ALL_FUTURE,
+ UNKNOWN_MODIFIED,
+ NOTHING_MODIFIED
+ };
+
+ enum WhichOccurrences {
+ NONE,
+ ONLY_THIS_ONE,
+ ONLY_FUTURE,
+ ALL
+ };
+
+ enum OccurrenceAction {
+ CUT,
+ COPY,
+ EDIT
+ };
static void fitDialogToScreen( TQWidget *widget, bool force=false );
KConfig *config() const;
diff --git a/korganizer/kogroupware.cpp b/korganizer/kogroupware.cpp
index 7b017cc4..0edcdc9c 100644
--- a/korganizer/kogroupware.cpp
+++ b/korganizer/kogroupware.cpp
@@ -73,8 +73,8 @@ KOGroupware *KOGroupware::instance()
}
- KOGroupware::KOGroupware( CalendarView* view, KCal::CalendarResources* cal )
- : TQObject( 0, "kmgroupware_instance" ), mView( view ), mCalendar( cal )
+KOGroupware::KOGroupware( CalendarView* view, KCal::CalendarResources* cal )
+ : TQObject( 0, "kmgroupware_instance" ), mView( view ), mCalendar( cal ), mDoNotNotify( false )
{
// Set up the dir watch of the three incoming dirs
KDirWatch* watcher = KDirWatch::self();
@@ -105,10 +105,8 @@ void KOGroupware::slotViewNewIncidenceChanger( IncidenceChangerBase* changer )
// Call slot perhapsUploadFB if an incidence was added, changed or removed
connect( changer, TQT_SIGNAL( incidenceAdded( Incidence* ) ),
mFreeBusyManager, TQT_SLOT( slotPerhapsUploadFB() ) );
- connect( changer, TQT_SIGNAL( incidenceChanged( Incidence*, Incidence*, int ) ),
+ connect( changer, TQT_SIGNAL( incidenceChanged( Incidence*, Incidence*, KOGlobals::WhatChanged ) ),
mFreeBusyManager, TQT_SLOT( slotPerhapsUploadFB() ) );
- connect( changer, TQT_SIGNAL( incidenceChanged( Incidence*, Incidence* ) ),
- mFreeBusyManager, TQT_SLOT( slotPerhapsUploadFB() ) ) ;
connect( changer, TQT_SIGNAL( incidenceDeleted( Incidence * ) ),
mFreeBusyManager, TQT_SLOT( slotPerhapsUploadFB() ) );
}
@@ -179,6 +177,10 @@ void KOGroupware::incomingDirChanged( const TQString& path )
KCal::ScheduleMessage::Status status = message->status();
KCal::Incidence* incidence =
dynamic_cast<KCal::Incidence*>( message->event() );
+ if(!incidence) {
+ delete message;
+ return;
+ }
KCal::MailScheduler scheduler( mCalendar );
if ( action.startsWith( "accepted" ) || action.startsWith( "tentative" )
|| action.startsWith( "delegated" ) || action.startsWith( "counter" ) ) {
@@ -200,10 +202,10 @@ void KOGroupware::incomingDirChanged( const TQString& path )
}
}
if ( KOPrefs::instance()->outlookCompatCounterProposals() || !action.startsWith( "counter" ) )
- scheduler.acceptTransaction( incidence, method, status );
+ scheduler.acceptTransaction( incidence, method, status, receiver );
} else if ( action.startsWith( "cancel" ) )
// Delete the old incidence, if one is present
- scheduler.acceptTransaction( incidence, KCal::Scheduler::Cancel, status );
+ scheduler.acceptTransaction( incidence, KCal::Scheduler::Cancel, status, receiver );
else if ( action.startsWith( "reply" ) ) {
if ( method != Scheduler::Counter ) {
scheduler.acceptTransaction( incidence, method, status );
@@ -211,13 +213,13 @@ void KOGroupware::incomingDirChanged( const TQString& path )
// accept counter proposal
scheduler.acceptCounterProposal( incidence );
// send update to all attendees
- sendICalMessage( mView, Scheduler::Request, incidence );
+ sendICalMessage( mView, Scheduler::Request, incidence, KOGlobals::INCIDENCEEDITED, false );
}
} else
kdError(5850) << "Unknown incoming action " << action << endl;
if ( action.startsWith( "counter" ) ) {
- mView->editIncidence( incidence, true );
+ mView->editIncidence( incidence, TQDate(), true );
KOIncidenceEditor *tmp = mView->editorDialog( incidence );
tmp->selectInvitationCounterProposal( true );
}
@@ -238,8 +240,9 @@ class KOInvitationFormatterHelper : public InvitationFormatterHelper
*/
bool KOGroupware::sendICalMessage( TQWidget* parent,
KCal::Scheduler::Method method,
- Incidence* incidence, bool isDeleting,
- bool statusChanged )
+ Incidence* incidence,
+ KOGlobals::HowChanged action,
+ bool attendeeStatusChanged )
{
// If there are no attendees, don't bother
if( incidence->attendees().isEmpty() )
@@ -267,16 +270,48 @@ bool KOGroupware::sendICalMessage( TQWidget* parent,
* mail. */
if ( incidence->attendees().count() > 1
|| incidence->attendees().first()->email() != incidence->organizer().email() ) {
- TQString type;
- if( incidence->type() == "Event") type = i18n("event");
- else if( incidence->type() == "Todo" ) type = i18n("task");
- else if( incidence->type() == "Journal" ) type = i18n("journal entry");
- else type = incidence->type();
- TQString txt = i18n( "This %1 includes other people. "
- "Should email be sent out to the attendees?" )
- .arg( type );
- rc = KMessageBox::questionYesNoCancel( parent, txt,
- i18n("Group Scheduling Email"), i18n("Send Email"), i18n("Do Not Send") );
+
+ TQString txt;
+ switch( action ) {
+ case KOGlobals::INCIDENCEEDITED:
+ txt = i18n( "You changed the invitation \"%1\".\n"
+ "Do you want to email the attendees an update message?" ).
+ arg( incidence->summary() );
+ break;
+ case KOGlobals::INCIDENCEDELETED:
+ Q_ASSERT( incidence->type() == "Event" || incidence->type() == "Todo" );
+ if ( incidence->type() == "Event" ) {
+ txt = i18n( "You removed the invitation \"%1\".\n"
+ "Do you want to email the attendees that the event is canceled?" ).
+ arg( incidence->summary() );
+ } else if ( incidence->type() == "Todo" ) {
+ txt = i18n( "You removed the invitation \"%1\".\n"
+ "Do you want to email the attendees that the todo is canceled?" ).
+ arg( incidence->summary() );
+ }
+ break;
+ case KOGlobals::INCIDENCEADDED:
+ if ( incidence->type() == "Event" ) {
+ txt = i18n( "The event \"%1\" includes other people.\n"
+ "Do you want to email the invitation to the attendees?" ).
+ arg( incidence->summary() );
+ } else if ( incidence->type() == "Todo" ) {
+ txt = i18n( "The todo \"%1\" includes other people.\n"
+ "Do you want to email the invitation to the attendees?" ).
+ arg( incidence->summary() );
+ } else {
+ txt = i18n( "This incidence includes other people. "
+ "Should an email be sent to the attendees?" );
+ }
+ break;
+ default:
+ kdError() << "Unsupported HowChanged action" << int( action ) << endl;
+ break;
+ }
+
+ rc = KMessageBox::questionYesNo(
+ parent, txt, i18n( "Group Scheduling Email" ),
+ KGuiItem( i18n( "Send Email" ) ), KGuiItem( i18n( "Do Not Send" ) ) );
} else {
return true;
}
@@ -291,32 +326,49 @@ bool KOGroupware::sendICalMessage( TQWidget* parent,
rc = KMessageBox::questionYesNo( parent, txt, TQString::null, i18n("Send Update"), i18n("Do Not Send") );
} else if( incidence->type() == "Event" ) {
TQString txt;
- if ( statusChanged && method == Scheduler::Request ) {
- txt = i18n( "Your status as an attendee of this event "
- "changed. Do you want to send a status update to the "
- "organizer of this event?" );
+ if ( attendeeStatusChanged && method == Scheduler::Request ) {
+ txt = i18n( "Your status as an attendee of this event changed. "
+ "Do you want to send a status update to the event organizer?" );
method = Scheduler::Reply;
rc = KMessageBox::questionYesNo( parent, txt, TQString::null, i18n("Send Update"), i18n("Do Not Send") );
} else {
- if( isDeleting )
- txt = i18n( "You are not the organizer of this event. "
- "Deleting it will bring your calendar out of sync "
- "with the organizers calendar. Do you really want "
- "to delete it?" );
- else
- txt = i18n( "You are not the organizer of this event. "
- "Editing it will bring your calendar out of sync "
- "with the organizers calendar. Do you really want "
- "to edit it?" );
- rc = KMessageBox::warningYesNo( parent, txt );
- return ( rc == KMessageBox::Yes );
+ if( action == KOGlobals::INCIDENCEDELETED ) {
+ const TQStringList myEmails = KOPrefs::instance()->allEmails();
+ bool askConfirmation = false;
+ for ( TQStringList::ConstIterator it = myEmails.begin(); it != myEmails.end(); ++it ) {
+ TQString email = *it;
+ Attendee *me = incidence->attendeeByMail(email);
+ if (me && (me->status()==KCal::Attendee::Accepted || me->status()==KCal::Attendee::Delegated)) {
+ askConfirmation = true;
+ break;
+ }
+ }
+
+ if ( !askConfirmation ) {
+ return true;
+ }
+
+ txt = i18n( "You had previously accepted an invitation to this event. "
+ "Do you want to send an updated response to the organizer "
+ "declining the invitation?" );
+ rc = KMessageBox::questionYesNo(
+ parent, txt, i18n( "Group Scheduling Email" ),
+ KGuiItem( i18n( "Send Update" ) ), KGuiItem( i18n( "Do Not Send" ) ) );
+ setDoNotNotify( rc == KMessageBox::No );
+ } else {
+ txt = i18n( "You are not the organizer of this event. Editing it will "
+ "bring your calendar out of sync with the organizer's calendar. "
+ "Do you really want to edit it?" );
+ rc = KMessageBox::warningYesNo( parent, txt );
+ return ( rc == KMessageBox::Yes );
+ }
}
} else {
kdWarning(5850) << "Groupware messages for Journals are not implemented yet!" << endl;
return true;
}
- if( rc == KMessageBox::Yes ) {
+ if ( rc == KMessageBox::Yes ) {
// We will be sending out a message here. Now make sure there is
// some summary
if( incidence->summary().isEmpty() )
@@ -327,10 +379,11 @@ bool KOGroupware::sendICalMessage( TQWidget* parent,
scheduler.performTransaction( incidence, method );
return true;
- } else if( rc == KMessageBox::No )
+ } else if ( rc == KMessageBox::No ) {
return true;
- else
+ } else {
return false;
+ }
}
void KOGroupware::sendCounterProposal(KCal::Calendar *calendar, KCal::Event * oldEvent, KCal::Event * newEvent) const
@@ -341,7 +394,9 @@ void KOGroupware::sendCounterProposal(KCal::Calendar *calendar, KCal::Event * ol
Incidence* tmp = oldEvent->clone();
tmp->setSummary( i18n("Counter proposal: %1").arg( newEvent->summary() ) );
tmp->setDescription( newEvent->description() );
- tmp->addComment( i18n("Proposed new meeting time: %1 - %2").arg( newEvent->dtStartStr(), newEvent->dtEndStr() ) );
+ tmp->addComment( i18n("Proposed new meeting time: %1 - %2").
+ arg( IncidenceFormatter::dateToString( newEvent->dtStart() ),
+ IncidenceFormatter::dateToString( newEvent->dtEnd() ) ) );
KCal::MailScheduler scheduler( calendar );
scheduler.performTransaction( tmp, Scheduler::Reply );
delete tmp;
diff --git a/korganizer/kogroupware.h b/korganizer/kogroupware.h
index 0af6a3c4..f6695de0 100644
--- a/korganizer/kogroupware.h
+++ b/korganizer/kogroupware.h
@@ -37,13 +37,16 @@
#ifndef KOGROUPWARE_H
#define KOGROUPWARE_H
+#include "koglobals.h"
+
#include <libkcal/calendarresources.h>
#include <libkcal/icalformat.h>
#include <libkcal/scheduler.h>
-#include <tqstring.h>
#include <kio/job.h>
+#include <tqstring.h>
+
using namespace KCal;
namespace KCal {
@@ -72,9 +75,10 @@ class KOGroupware : public QObject
Returns false if the user cancels the dialog, and true if the
user presses Yes og or No.
*/
- bool sendICalMessage( TQWidget* parent, KCal::Scheduler::Method method,
- Incidence* incidence, bool isDeleting = false,
- bool statusChanged = false );
+ bool sendICalMessage( TQWidget *parent, KCal::Scheduler::Method method,
+ Incidence* incidence,
+ KOGlobals::HowChanged action,
+ bool attendeeStatusChanged );
/**
Send counter proposal message.
@@ -83,12 +87,14 @@ class KOGroupware : public QObject
*/
void sendCounterProposal( KCal::Calendar* calendar, KCal::Event* oldEvent, KCal::Event *newEvent ) const;
- // THIS IS THE ACTUAL KM/KO API
- enum EventState { Accepted, ConditionallyAccepted, Declined, Request };
-
// convert the TNEF attachment to a vCard or iCalendar part
TQString msTNEFToVPart( const TQByteArray& tnef );
+ // DoNotNotify is a flag indicating that the user does not want
+ // updates sent back to the organizer.
+ void setDoNotNotify( bool notify ) { mDoNotNotify = notify; }
+ bool doNotNotify() { return mDoNotNotify; }
+
private slots:
/** Handle iCals given by KMail. */
void incomingDirChanged( const TQString& path );
@@ -106,6 +112,7 @@ class KOGroupware : public QObject
CalendarView *mView;
KCal::CalendarResources *mCalendar;
static FreeBusyManager *mFreeBusyManager;
+ bool mDoNotNotify;
};
#endif
diff --git a/korganizer/kogroupwareprefspage.ui b/korganizer/kogroupwareprefspage.ui
index d6f14f9a..a4e558fb 100644
--- a/korganizer/kogroupwareprefspage.ui
+++ b/korganizer/kogroupwareprefspage.ui
@@ -39,7 +39,7 @@
<cstring>TextLabel1</cstring>
</property>
<property name="text">
- <string>By publishing Free/Busy information, you allow others to take your calendar into account when inviting you for a meeting. Only the times you have already busy are published, not why they are busy.</string>
+ <string>By publishing Free/Busy information, you allow others to take your calendar into account when inviting you for a meeting. Only the times you have already busy are published, not why they are busy. For Kolab2 Server leave this disabled (the information is generated on the server).</string>
</property>
<property name="alignment">
<set>WordBreak|AlignVCenter</set>
@@ -182,8 +182,7 @@ Note: If KOrganizer is acting as a KDE Kolab client, this is not required, as th
</property>
<property name="whatsThis" stdset="0">
<string>Enter the URL for the server on which your Free/Busy information shall be published here.
-Ask the server administrator for this information.
-Here is a Kolab2 server URL example: "webdavs://kolab2.com/freebusy/joe@kolab2.com.ifb"</string>
+Ask the server administrator for this information.</string>
</property>
</widget>
<widget class="QCheckBox" row="7" column="0" rowspan="1" colspan="2">
@@ -278,8 +277,7 @@ A Kolab2 server specificity: Registered your UID (Unique IDentifier). By default
</property>
<property name="whatsThis" stdset="0">
<string>Enter the URL for the server on which your Free/Busy information shall be published here.
-Ask the server administrator for this information.
-Here is a Kolab2 server URL example: "webdavs://kolab2.com/freebusy/joe@kolab2.com.ifb"</string>
+Ask the server administrator for this information.</string>
</property>
</widget>
</grid>
@@ -385,9 +383,11 @@ Here is a Kolab2 server URL example: "webdavs://kolab2.com/freebusy/joe@kolab2.c
<property name="whatsThis" stdset="0">
<string>Enter the URL for the server on which the Free/Busy information is published here.
Ask the server administrator for this information.
-Here is a Kolab2 server URL example: "webdavs://kolab2.com/freebusy/"
+Here is a Kolab2 Server URL example: "https://kolab2.example.com/freebusy/"
Here is a generic server example: "http://myserver.net/%u@%d/?internal.ics"
-%u expands to the username, and %d expands to the domain name.</string>
+%u expands to the username, and %d expands to the domain name.
+Alternatively, you can specify a full path to the Free/Busy file,
+For example: "https://kolab2.example.com/freebusy/user.xfb"</string>
</property>
</widget>
<widget class="QLineEdit">
@@ -400,9 +400,11 @@ Here is a generic server example: "http://myserver.net/%u@%d/?internal.ics"
<property name="whatsThis" stdset="0">
<string>Enter the URL for the server on which the Free/Busy information is published here.
Ask the server administrator for this information.
-Here is a Kolab2 server URL example: "webdavs://kolab2.com/freebusy/"
+Here is a Kolab2 Server URL example: "https://kolab2.example.com/freebusy/"
Here is a generic server example: "http://myserver.net/%u@%d/?internal.ics"
-%u expands to the username, and %d expands to the domain name.</string>
+%u expands to the username, and %d expands to the domain name.
+Alternatively, you can specify a full path to the Free/Busy file,
+For example: "https://kolab2.example.com/freebusy/user.xfb"</string>
</property>
</widget>
</hbox>
diff --git a/korganizer/kohelper.cpp b/korganizer/kohelper.cpp
index 827279fe..3b7bd877 100644
--- a/korganizer/kohelper.cpp
+++ b/korganizer/kohelper.cpp
@@ -62,23 +62,3 @@ TQColor KOHelper::resourceColor( KCal::Calendar*calendar, KCal::Incidence*incide
}
return resourceColor;
}
-
-TQString KOHelper::resourceLabel(KCal::Calendar * calendar, KCal::Incidence * incidence)
-{
- KCal::CalendarResources *calendarResource = dynamic_cast<KCal::CalendarResources*>( calendar );
- if ( !calendarResource || ! incidence )
- return TQString();
-
- KCal::ResourceCalendar *resourceCalendar = calendarResource->resource( incidence );
- if( resourceCalendar ) {
- if ( !resourceCalendar->subresources().isEmpty() ) {
- TQString subRes = resourceCalendar->subresourceIdentifier( incidence );
- if ( subRes.isEmpty() )
- return resourceCalendar->resourceName();
- return resourceCalendar->labelForSubresource( subRes );
- }
- return resourceCalendar->resourceName();
- }
-
- return TQString();
-}
diff --git a/korganizer/kohelper.h b/korganizer/kohelper.h
index b7f61b79..07d91058 100644
--- a/korganizer/kohelper.h
+++ b/korganizer/kohelper.h
@@ -42,12 +42,6 @@ class KDE_EXPORT KOHelper
to a subresource, the color for the subresource is returned (if set).
*/
static TQColor resourceColor( KCal::Calendar*calendar, KCal::Incidence*incidence );
-
- /**
- Returns the resource label the given incidence belongs to.
- */
- static TQString resourceLabel( KCal::Calendar *calendar, KCal::Incidence *incidence );
-
};
#endif
diff --git a/korganizer/koincidenceeditor.cpp b/korganizer/koincidenceeditor.cpp
index 3eb4920f..240497e1 100644
--- a/korganizer/koincidenceeditor.cpp
+++ b/korganizer/koincidenceeditor.cpp
@@ -45,6 +45,7 @@
#include <libkcal/calendarlocal.h>
#include <libkcal/incidence.h>
#include <libkcal/icalformat.h>
+#include <libkcal/resourcecalendar.h>
#include "koprefs.h"
#include "koglobals.h"
@@ -58,7 +59,8 @@ KOIncidenceEditor::KOIncidenceEditor( const TQString &caption,
Calendar *calendar, TQWidget *parent )
: KDialogBase( Tabbed, caption, Ok | Apply | Cancel | Default, Ok,
parent, 0, false, false ),
- mAttendeeEditor( 0 ), mIsCounter( false )
+ mAttendeeEditor( 0 ), mResource( 0 ), mIsCounter( false ), mIsCreateTask( false ),
+ mRecurIncidence( 0 ), mRecurIncidenceAfterDissoc( 0 )
{
// Set this to be the group leader for all subdialogs - this means
// modal subdialogs will only affect this dialog, not the other windows
@@ -349,14 +351,14 @@ void KOIncidenceEditor::createEmbeddedURLPages( Incidence *i )
void KOIncidenceEditor::openURL( const KURL &url )
{
TQString uri = url.url();
- UriHandler::process( uri );
+ UriHandler::process( this, uri );
}
void KOIncidenceEditor::addAttachments( const TQStringList &attachments,
const TQStringList &mimeTypes,
bool inlineAttachments )
{
- emit signalAddAttachments( attachments, mimeTypes, inlineAttachments );
+ emit signalAddAttachments( attachments, mimeTypes, inlineAttachments );
}
void KOIncidenceEditor::addAttendees( const TQStringList &attendees )
@@ -365,7 +367,33 @@ void KOIncidenceEditor::addAttendees( const TQStringList &attendees )
for ( it = attendees.begin(); it != attendees.end(); ++it ) {
TQString name, email;
KABC::Addressee::parseEmailAddress( *it, name, email );
- mAttendeeEditor->insertAttendee( new Attendee( name, email ) );
+ mAttendeeEditor->insertAttendee( new Attendee( name, email, true, Attendee::NeedsAction ) );
+ }
+}
+
+void KOIncidenceEditor::setResource( ResourceCalendar *res, const TQString &subRes )
+{
+ TQString label;
+ if ( res ) {
+ if ( !res->subresources().isEmpty() && !subRes.isEmpty() ) {
+ label = res->labelForSubresource( subRes );
+ } else {
+ label = res->resourceName();
+ }
+ }
+
+ mResource = res;
+ mSubResource = subRes;
+}
+
+
+void KOIncidenceEditor::selectCreateTask( bool enable )
+{
+ mIsCreateTask = enable;
+ if ( mIsCreateTask ) {
+ setCaption( i18n( "Create to-do" ) );
+ setButtonOK( i18n( "Create to-do" ) );
+ showButtonApply( false );
}
}
@@ -375,9 +403,16 @@ void KOIncidenceEditor::selectInvitationCounterProposal(bool enable)
if ( mIsCounter ) {
setCaption( i18n( "Counter proposal" ) );
setButtonOK( i18n( "Counter proposal" ) );
- enableButtonApply( false );
+ showButtonApply( false );
}
}
+void KOIncidenceEditor::setRecurringIncidence ( Incidence *originalIncidence,
+ Incidence *incAfterDissociation )
+{
+ mRecurIncidence = originalIncidence;
+ mRecurIncidenceAfterDissoc = incAfterDissociation;
+}
+
#include "koincidenceeditor.moc"
diff --git a/korganizer/koincidenceeditor.h b/korganizer/koincidenceeditor.h
index 35c4c45b..91f22afd 100644
--- a/korganizer/koincidenceeditor.h
+++ b/korganizer/koincidenceeditor.h
@@ -28,6 +28,7 @@
#include <kdialogbase.h>
#include <kurl.h>
+class TQDate;
class TQDateTime;
namespace KPIM {
@@ -42,9 +43,10 @@ class KOEditorDetails;
class KOAttendeeEditor;
namespace KCal {
-class Calendar;
-class CalendarLocal;
-class Incidence;
+ class Calendar;
+ class CalendarLocal;
+ class Incidence;
+ class ResourceCalendar;
}
using namespace KCal;
using namespace KOrg;
@@ -54,7 +56,7 @@ using namespace KOrg;
*/
class KOIncidenceEditor : public KDialogBase
{
- Q_OBJECT
+ Q_OBJECT
public:
/**
Construct new IncidenceEditor.
@@ -64,15 +66,31 @@ class KOIncidenceEditor : public KDialogBase
virtual ~KOIncidenceEditor();
/** This incidence has been modified externally */
- virtual void modified (int /*change*/=0) {}
+ virtual void modified() {}
virtual void reload() = 0;
+ virtual void setResource( ResourceCalendar *res, const TQString &subRes );
virtual void selectInvitationCounterProposal( bool enable );
+ virtual void selectCreateTask( bool enable );
+
+ /**
+ This should be called when editing only one occurrence of a recurring incidence,
+ before showing the editor.
+
+ It gives the editor a pointer to the original incidence, which contains all occurrences
+ and a pointer to the original incidence already dissociated from the event (mEvent).
+
+ If the user presses ok/apply the changes made to the incAfterDissociation are commited
+ to the callendar through mChanger.
+
+ If the user presses cancel we restore originalIncidence and all dissociations are discarded
+ */
+ void setRecurringIncidence( Incidence *originalIncidence, Incidence *incAfterDissociation );
public slots:
/** Edit an existing todo. */
- virtual void editIncidence(Incidence *, Calendar *) = 0;
+ virtual void editIncidence(Incidence *, const TQDate &, Calendar *) = 0;
virtual void setIncidenceChanger( IncidenceChangerBase *changer ) {
mChanger = changer; }
/** Initialize editor. This function creates the tab widgets. */
@@ -88,7 +106,6 @@ class KOIncidenceEditor : public KDialogBase
*/
void addAttendees( const TQStringList &attendees );
-
signals:
void deleteAttendee( Incidence * );
@@ -153,7 +170,14 @@ class KOIncidenceEditor : public KDialogBase
TQMap<TQWidget*, KPIM::DesignerFields*> mDesignerFieldForWidget;
TQPtrList<TQWidget> mEmbeddedURLPages;
TQPtrList<TQWidget> mAttachedDesignerFields;
+ ResourceCalendar *mResource;
+ TQString mSubResource;
bool mIsCounter;
+ bool mIsCreateTask;
+
+ Incidence *mRecurIncidence;
+ Incidence *mRecurIncidenceAfterDissoc;
+
};
#endif
diff --git a/korganizer/koincidencetooltip.cpp b/korganizer/koincidencetooltip.cpp
index 8b3f1175..2b2a80f2 100644
--- a/korganizer/koincidencetooltip.cpp
+++ b/korganizer/koincidencetooltip.cpp
@@ -33,19 +33,24 @@
some improvements by Mikolaj Machowski
*/
-void KOIncidenceToolTip::add ( TQWidget * widget, Incidence *incidence,
- TQToolTipGroup * group, const TQString & longText )
+void KOIncidenceToolTip::add ( TQWidget *widget, Calendar *calendar,
+ Incidence *incidence, const TQDate &date,
+ TQToolTipGroup *group, const TQString &longText )
{
- if ( !widget || !incidence ) return;
- TQToolTip::add(widget, IncidenceFormatter::toolTipString( incidence ), group, longText);
+ if ( !widget || !incidence ) {
+ return;
+ }
+ TQToolTip::add( widget, IncidenceFormatter::toolTipStr( calendar, incidence, date ), group, longText );
}
-void KOIncidenceToolTip::add(KOAgendaItem * item, Incidence * incidence, TQToolTipGroup * group)
+void KOIncidenceToolTip::add( KOAgendaItem *item, Calendar *calendar,
+ Incidence *incidence, const TQDate &date,
+ TQToolTipGroup *group )
{
Q_UNUSED( incidence );
Q_UNUSED( group );
TQToolTip::remove( item );
- new KOIncidenceToolTip( item );
+ new KOIncidenceToolTip( item, calendar, date );
}
void KOIncidenceToolTip::maybeTip(const TQPoint & pos)
@@ -55,6 +60,6 @@ void KOIncidenceToolTip::maybeTip(const TQPoint & pos)
if ( !item )
return;
if ( !mText )
- mText = IncidenceFormatter::toolTipString( item->incidence() );
+ mText = IncidenceFormatter::toolTipStr( mCalendar, item->incidence(), mDate );
tip( TQRect( TQPoint( 0, 0 ), item->size() ), mText );
}
diff --git a/korganizer/koincidencetooltip.h b/korganizer/koincidencetooltip.h
index 11b5d39a..348ab890 100644
--- a/korganizer/koincidencetooltip.h
+++ b/korganizer/koincidencetooltip.h
@@ -27,6 +27,7 @@
namespace KCal
{
+class Calendar;
class Incidence;
}
using namespace KCal;
@@ -39,19 +40,24 @@ class KOAgendaItem;
class KOIncidenceToolTip : public QToolTip
{
public:
- KOIncidenceToolTip(TQWidget * widget, TQToolTipGroup * group = 0 ):TQToolTip (widget, group),mText(0) {}
+ KOIncidenceToolTip( TQWidget *widget, Calendar *calendar, const TQDate &date, TQToolTipGroup *group = 0 )
+ : TQToolTip (widget, group), mCalendar( calendar ), mDate( date ), mText(0) {}
/* ~KOIncidenceToolTip();*/
public:
- static void add ( TQWidget * widget, Incidence *incidence,
- TQToolTipGroup * group = 0, const TQString & longText = "" );
- static void add( KOAgendaItem *item, Incidence *incidence = 0,
+ static void add ( TQWidget *widget, Calendar *calendar,
+ Incidence *incidence, const TQDate &date=TQDate(),
+ TQToolTipGroup *group = 0, const TQString &longText = "" );
+ static void add( KOAgendaItem *item, Calendar *calendar,
+ Incidence *incidence = 0, const TQDate &date=TQDate(),
TQToolTipGroup *group = 0 );
/* reimplmented from TQToolTip */
void maybeTip( const TQPoint &pos );
private:
+ Calendar *mCalendar;
+ TQDate mDate;
TQString mText;
};
diff --git a/korganizer/kojournaleditor.cpp b/korganizer/kojournaleditor.cpp
index a50ba1fe..b53e071e 100644
--- a/korganizer/kojournaleditor.cpp
+++ b/korganizer/kojournaleditor.cpp
@@ -62,8 +62,10 @@ void KOJournalEditor::init()
void KOJournalEditor::reload()
{
- kdDebug(5851)<<"reloading Journal"<<endl;
- if ( mJournal ) readJournal( mJournal );
+ kdDebug(5851) << "reloading Journal" << endl;
+ if ( mJournal ) {
+ readJournal( mJournal, TQDate() );
+ }
}
void KOJournalEditor::setupGeneral()
@@ -94,7 +96,7 @@ void KOJournalEditor::setupGeneral()
mGeneral->finishSetup();
}
-void KOJournalEditor::editIncidence( Incidence *incidence, Calendar * )
+void KOJournalEditor::editIncidence( Incidence *incidence, const TQDate &date, Calendar * )
{
Journal *journal=dynamic_cast<Journal*>(incidence);
if (journal)
@@ -102,7 +104,7 @@ void KOJournalEditor::editIncidence( Incidence *incidence, Calendar * )
init();
mJournal = journal;
- readJournal(mJournal);
+ readJournal(mJournal, date);
}
}
@@ -140,7 +142,7 @@ bool KOJournalEditor::processInput()
if ( mJournal ) {
Journal *oldJournal = mJournal->clone();
writeJournal( mJournal );
- mChanger->changeIncidence( oldJournal, mJournal );
+ mChanger->changeIncidence( oldJournal, mJournal, KOGlobals::NOTHING_MODIFIED, this );
delete oldJournal;
} else {
mJournal = new Journal;
@@ -149,8 +151,7 @@ bool KOJournalEditor::processInput()
writeJournal( mJournal );
- if ( !mChanger->addIncidence( mJournal, this ) ) {
- KODialogManager::errorSaveIncidence( this, mJournal );
+ if ( !mChanger->addIncidence( mJournal, mResource, mSubResource, this ) ) {
delete mJournal;
mJournal = 0;
return false;
@@ -176,10 +177,10 @@ void KOJournalEditor::setDate( const TQDate &date )
mDetails->setDefaults();
}
-void KOJournalEditor::readJournal( Journal *journal )
+void KOJournalEditor::readJournal( Journal *journal, const TQDate &date )
{
kdDebug(5851)<<"read Journal"<<endl;
- mGeneral->readJournal( journal );
+ mGeneral->readJournal( journal, date );
mDetails->readEvent( journal );
}
@@ -201,10 +202,10 @@ int KOJournalEditor::msgItemDelete()
i18n("KOrganizer Confirmation"), KGuiItem( i18n("Delete"), "editdelete" ));
}
-void KOJournalEditor::modified( int /*modification*/)
+void KOJournalEditor::modified()
{
- // Play dump, just reload the Journal. This dialog has become so complicated that
- // there is no point in trying to be smart here...
+ // Play dump, just reload the Journal. This dialog has become so complicated
+ // that there is no point in trying to be smart here...
reload();
}
@@ -215,7 +216,7 @@ void KOJournalEditor::loadTemplate( /*const*/ CalendarLocal& cal)
KMessageBox::error( this,
i18n("Template does not contain a valid journal.") );
} else {
- readJournal( journals.first() );
+ readJournal( journals.first(), TQDate() );
}
}
diff --git a/korganizer/kojournaleditor.h b/korganizer/kojournaleditor.h
index 75edb182..291940cf 100644
--- a/korganizer/kojournaleditor.h
+++ b/korganizer/kojournaleditor.h
@@ -69,12 +69,12 @@ class KOJournalEditor : public KOIncidenceEditor
*/
void setTexts( const TQString &summary, const TQString &description = TQString::null );
/** Edit an existing Journal. */
- void editIncidence(Incidence *, Calendar *);
+ void editIncidence(Incidence *, const TQDate &date, Calendar *);
/** Set widgets to default values */
void setDate( const TQDate &date );
/** Read event object and setup widgets accordingly */
- void readJournal( Journal * );
+ void readJournal( Journal *, const TQDate &date );
/** Write event settings to event object */
void writeJournal( Journal * );
@@ -86,7 +86,7 @@ class KOJournalEditor : public KOIncidenceEditor
bool processInput();
/** This Journal has been modified externally */
- void modified (int change=0);
+ void modified();
protected slots:
void loadDefaults();
diff --git a/korganizer/kojournalview.cpp b/korganizer/kojournalview.cpp
index e8de3dae..74a0f17c 100644
--- a/korganizer/kojournalview.cpp
+++ b/korganizer/kojournalview.cpp
@@ -71,20 +71,24 @@ void KOJournalView::appendJournal( Journal*journal, const TQDate &dt)
entry->setDate( dt );
entry->setIncidenceChanger( mChanger );
entry->show();
- connect( this, TQT_SIGNAL(flushEntries()), entry, TQT_SIGNAL(flushEntries()) );
- connect( this, TQT_SIGNAL(setIncidenceChangerSignal( IncidenceChangerBase * ) ),
- entry, TQT_SLOT(setIncidenceChanger( IncidenceChangerBase * ) ) );
- connect( this, TQT_SIGNAL( journalEdited( Journal* ) ),
- entry, TQT_SLOT( journalEdited( Journal* ) ) );
- connect( this, TQT_SIGNAL( journalDeleted( Journal* ) ),
- entry, TQT_SLOT( journalDeleted( Journal* ) ) );
-
- connect( entry, TQT_SIGNAL( editIncidence( Incidence* ) ),
- this, TQT_SIGNAL( editIncidenceSignal( Incidence* ) ) );
- connect( entry, TQT_SIGNAL( deleteIncidence( Incidence* ) ),
- this, TQT_SIGNAL( deleteIncidenceSignal( Incidence* ) ) );
- connect( entry, TQT_SIGNAL( newJournal( const TQDate & ) ),
- this, TQT_SIGNAL( newJournalSignal( const TQDate & ) ) );
+ connect( this, TQT_SIGNAL(flushEntries()),
+ entry, TQT_SIGNAL(flushEntries()) );
+
+ connect( this, TQT_SIGNAL(setIncidenceChangerSignal(IncidenceChangerBase *)),
+ entry, TQT_SLOT(setIncidenceChanger( IncidenceChangerBase *)) );
+
+ connect( this, TQT_SIGNAL(journalEdited(Journal *)),
+ entry, TQT_SLOT(journalEdited(Journal *)) );
+ connect( this, TQT_SIGNAL(journalDeleted(Journal *)),
+ entry, TQT_SLOT(journalDeleted(Journal *)) );
+
+ connect( entry, TQT_SIGNAL(editIncidence(Incidence *,const TQDate &)),
+ this, TQT_SIGNAL(editIncidenceSignal(Incidence *,const TQDate &)) );
+ connect( entry, TQT_SIGNAL(deleteIncidence(Incidence *)),
+ this, TQT_SIGNAL(deleteIncidenceSignal(Incidence *)) );
+
+ connect( entry, TQT_SIGNAL(newJournal(ResourceCalendar *,const TQString &,const TQDate &)),
+ this, TQT_SIGNAL(newJournalSignal(ResourceCalendar *,const TQString &,const TQDate &)) );
mEntries.insert( dt, entry );
}
@@ -134,16 +138,18 @@ void KOJournalView::flushView()
emit flushEntries();
}
-void KOJournalView::showDates(const TQDate &start, const TQDate &end)
+void KOJournalView::showDates( const TQDate &start, const TQDate &end )
{
// kdDebug(5850) << "KOJournalView::showDates(): "<<start.toString().latin1()<<" - "<<end.toString().latin1() << endl;
clearEntries();
- if ( end<start ) return;
+ if ( end < start ) {
+ return;
+ }
Journal::List::ConstIterator it;
Journal::List jnls;
- TQDate d=start;
- for ( TQDate d=start; d<=end; d=d.addDays(1) ) {
+ TQDate d = start;
+ for ( TQDate d = start; d <= end; d = d.addDays( 1 ) ) {
jnls = calendar()->journals( d );
for ( it = jnls.begin(); it != jnls.end(); ++it ) {
appendJournal( *it, d );
@@ -155,15 +161,17 @@ void KOJournalView::showDates(const TQDate &start, const TQDate &end)
}
}
-void KOJournalView::showIncidences( const Incidence::List &incidences )
+void KOJournalView::showIncidences( const Incidence::List &incidences, const TQDate & )
{
// kdDebug(5850) << "KOJournalView::showIncidences(): "<< endl;
clearEntries();
Incidence::List::const_iterator it;
- for ( it=incidences.constBegin(); it!=incidences.constEnd(); ++it) {
- if ((*it) && ( (*it)->type()=="Journal" ) ) {
- Journal*j = static_cast<Journal*>(*it);
- if ( j ) appendJournal( j, j->dtStart().date() );
+ for ( it = incidences.constBegin(); it != incidences.constEnd(); ++it ) {
+ if ( (*it) && ( (*it)->type() == "Journal" ) ) {
+ Journal *j = static_cast<Journal*>(*it);
+ if ( j ) {
+ appendJournal( j, j->dtStart().date() );
+ }
}
}
}
@@ -202,7 +210,8 @@ void KOJournalView::setIncidenceChanger( IncidenceChangerBase *changer )
void KOJournalView::newJournal()
{
- emit newJournalSignal( TQDate::currentDate() );
+ emit newJournalSignal( 0/*ResourceCalendar*/, TQString()/*subResource*/,
+ TQDate::currentDate() );
}
#include "kojournalview.moc"
diff --git a/korganizer/kojournalview.h b/korganizer/kojournalview.h
index 9af95537..fbc38efb 100644
--- a/korganizer/kojournalview.h
+++ b/korganizer/kojournalview.h
@@ -25,8 +25,8 @@
#define KOJOURNALVIEW_H
#include <korganizer/baseview.h>
-#include "journalentry.h"
+class JournalDateEntry;
class JournalEntry;
class TQScrollView;
class TQVBox;
@@ -48,7 +48,7 @@ class KOJournalView : public KOrg::BaseView
virtual int currentDateCount();
virtual Incidence::List selectedIncidences();
- DateList selectedDates() { return DateList(); }
+ DateList selectedIncidenceDates() { return DateList(); }
void appendJournal( Journal*journal, const TQDate &dt);
CalPrinterBase::PrintType printType();
@@ -60,7 +60,7 @@ class KOJournalView : public KOrg::BaseView
void flushView();
void showDates( const TQDate &start, const TQDate &end );
- void showIncidences( const Incidence::List &incidenceList );
+ void showIncidences( const Incidence::List &incidenceList, const TQDate &date );
void changeIncidenceDisplay( Incidence *, int );
void setIncidenceChanger( IncidenceChangerBase *changer );
diff --git a/korganizer/kolistview.cpp b/korganizer/kolistview.cpp
index 7ca342e8..59b7f17e 100644
--- a/korganizer/kolistview.cpp
+++ b/korganizer/kolistview.cpp
@@ -28,6 +28,7 @@
#include <tqlayout.h>
#include <tqpopupmenu.h>
#include <tqcursor.h>
+#include <tqstyle.h>
#include <klocale.h>
#include <kdebug.h>
@@ -45,30 +46,39 @@
#include "kolistview.h"
#include "kolistview.moc"
+enum {
+ Summary_Column = 0,
+ Reminder_Column,
+ Recurs_Column,
+ StartDateTime_Column,
+ EndDateTime_Column,
+ Categories_Column
+};
+
KOListViewToolTip::KOListViewToolTip( TQWidget* parent,
- KListView* lv )
- :TQToolTip(parent)
+ Calendar *calendar,
+ KListView *lv )
+ :TQToolTip( parent ), mCalendar( calendar )
{
- eventlist=lv;
+ eventlist = lv;
}
-void KOListViewToolTip::maybeTip( const TQPoint & pos)
+void KOListViewToolTip::maybeTip( const TQPoint &pos )
{
TQRect r;
- TQListViewItem *it = eventlist->itemAt(pos);
- KOListViewItem *i = static_cast<KOListViewItem*>(it);
+ TQListViewItem *it = eventlist->itemAt( pos );
+ KOListViewItem *i = static_cast<KOListViewItem*>( it );
- if( i && KOPrefs::instance()->mEnableToolTips ) {
+ if ( i && KOPrefs::instance()->mEnableToolTips ) {
/* Calculate the rectangle. */
- r=eventlist->itemRect( it );
+ r = eventlist->itemRect( it );
/* Show the tip */
- TQString tipText( IncidenceFormatter::toolTipString( i->data() ) );
+ TQString tipText( IncidenceFormatter::toolTipStr( mCalendar, i->data() ) );
if ( !tipText.isEmpty() ) {
- tip(r, tipText);
+ tip( r, tipText );
}
}
-
}
/**
@@ -91,132 +101,127 @@ class KOListView::ListItemVisitor : public IncidenceBase::Visitor
bool KOListView::ListItemVisitor::visit( Event *e )
{
- mItem->setText(0,e->summary());
+ mItem->setText( Summary_Column, e->summary() );
if ( e->isAlarmEnabled() ) {
static const TQPixmap alarmPxmp = KOGlobals::self()->smallIcon( "bell" );
- mItem->setPixmap(1,alarmPxmp);
- mItem->setSortKey(1,"1");
+ mItem->setPixmap( Reminder_Column, alarmPxmp );
+ mItem->setSortKey( Reminder_Column, "1" );
+ } else {
+ mItem->setSortKey( Reminder_Column, "0" );
}
- else
- mItem->setSortKey(1,"0");
if ( e->doesRecur() ) {
static const TQPixmap recurPxmp = KOGlobals::self()->smallIcon( "recur" );
- mItem->setPixmap(2,recurPxmp);
- mItem->setSortKey(2,"1");
+ mItem->setPixmap( Recurs_Column, recurPxmp );
+ mItem->setSortKey( Recurs_Column, "1" );
+ } else {
+ mItem->setSortKey( Recurs_Column, "0" );
}
- else
- mItem->setSortKey(2,"0");
-
- static const TQPixmap eventPxmp = KOGlobals::self()->smallIcon( "appointment" );
- mItem->setPixmap(0, eventPxmp);
- mItem->setText( 3,e->dtStartDateStr());
- mItem->setSortKey( 3, e->dtStart().toString(Qt::ISODate));
- if (e->doesFloat()) mItem->setText(4, "---"); else {
- mItem->setText( 4, e->dtStartTimeStr() );
- mItem->setSortKey( 4,e->dtStart().time().toString(Qt::ISODate));
- }
- mItem->setText( 5,e->dtEndDateStr());
- mItem->setSortKey( 5, e->dtEnd().toString(Qt::ISODate));
- if (e->doesFloat()) mItem->setText(6, "---"); else {
- mItem->setText( 6, e->dtEndTimeStr() );
- mItem->setSortKey( 6, e->dtEnd().time().toString(Qt::ISODate));
+ TQPixmap eventPxmp;
+ if ( e->customProperty( "KABC", "BIRTHDAY" ) == "YES" ) {
+ if ( e->customProperty( "KABC", "ANNIVERSARY" ) == "YES" ) {
+ eventPxmp = KOGlobals::self()->smallIcon( "calendaranniversary" );
+ } else {
+ eventPxmp = KOGlobals::self()->smallIcon( "calendarbirthday" );
+ }
+ } else {
+ eventPxmp = KOGlobals::self()->smallIcon( "appointment" );
}
- mItem->setText( 7,e->categoriesStr());
+
+ mItem->setPixmap( Summary_Column, eventPxmp );
+
+ TQString startDateTime;
+ TQString endDateTime;
+
+ mItem->setText( StartDateTime_Column, IncidenceFormatter::dateTimeToString( e->dtStart(), e->doesFloat() ) );
+ mItem->setSortKey( StartDateTime_Column, e->dtStart().toString( Qt::ISODate ) );
+ mItem->setText( EndDateTime_Column, IncidenceFormatter::dateTimeToString( e->dtEnd(), e->doesFloat() ) );
+ mItem->setSortKey( EndDateTime_Column, e->dtEnd().toString( Qt::ISODate ) );
+ mItem->setText( Categories_Column, e->categoriesStr() );
return true;
}
-bool KOListView::ListItemVisitor::visit(Todo *t)
+bool KOListView::ListItemVisitor::visit( Todo *t )
{
static const TQPixmap todoPxmp = KOGlobals::self()->smallIcon( "todo" );
static const TQPixmap todoDonePxmp = KOGlobals::self()->smallIcon( "checkedbox" );
- mItem->setPixmap(0, t->isCompleted() ? todoDonePxmp : todoPxmp );
- mItem->setText(0,t->summary());
+ mItem->setPixmap(Summary_Column, t->isCompleted() ? todoDonePxmp : todoPxmp );
+ mItem->setText(Summary_Column, t->summary());
if ( t->isAlarmEnabled() ) {
static const TQPixmap alarmPxmp = KOGlobals::self()->smallIcon( "bell" );
- mItem->setPixmap(1,alarmPxmp);
- mItem->setSortKey(1, "1");
+ mItem->setPixmap( Reminder_Column, alarmPxmp );
+ mItem->setSortKey( Reminder_Column, "1" );
+ } else {
+ mItem->setSortKey( Reminder_Column, "0" );
}
- else
- mItem->setSortKey(1, "0");
if ( t->doesRecur() ) {
static const TQPixmap recurPxmp = KOGlobals::self()->smallIcon( "recur" );
- mItem->setPixmap(2,recurPxmp);
- mItem->setSortKey(2, "1");
- }
- else
- mItem->setSortKey(2, "0");
-
- if (t->hasStartDate()) {
- mItem->setText(3,t->dtStartDateStr());
- mItem->setSortKey(3,t->dtStart().toString(Qt::ISODate));
- if (t->doesFloat()) {
- mItem->setText(4,"---");
- } else {
- mItem->setText(4,t->dtStartTimeStr());
- mItem->setSortKey( 4, t->dtStart().time().toString(Qt::ISODate) );
- }
+ mItem->setPixmap( Recurs_Column, recurPxmp );
+ mItem->setSortKey( Recurs_Column, "1" );
} else {
- mItem->setText(3,"---");
- mItem->setText(4,"---");
+ mItem->setSortKey( Recurs_Column, "0" );
}
- if (t->hasDueDate()) {
- mItem->setText(5,t->dtDueDateStr());
- mItem->setSortKey( 5, t->dtDue().toString(Qt::ISODate) );
- if (t->doesFloat()) {
- mItem->setText(6,"---");
- } else {
- mItem->setText(6,t->dtDueTimeStr());
- mItem->setSortKey( 6, t->dtDue().time().toString(Qt::ISODate) );
- }
+ if ( t->hasStartDate() ) {
+ mItem->setText( StartDateTime_Column, IncidenceFormatter::dateTimeToString( t->dtStart(), t->doesFloat() ) );
+ mItem->setSortKey( StartDateTime_Column, t->dtStart().toString( Qt::ISODate ) );
} else {
- mItem->setText(5,"---");
- mItem->setText(6,"---");
+ mItem->setText( StartDateTime_Column, "---" );
}
- mItem->setText(7,t->categoriesStr());
+ if ( t->hasDueDate() ) {
+ mItem->setText( EndDateTime_Column, IncidenceFormatter::dateTimeToString( t->dtDue(), t->doesFloat() ) );
+ mItem->setSortKey( EndDateTime_Column, t->dtDue().toString( Qt::ISODate ) );
+ } else {
+ mItem->setText( EndDateTime_Column, "---" );
+ }
+ mItem->setText( Categories_Column, t->categoriesStr() );
return true;
}
-bool KOListView::ListItemVisitor::visit(Journal *t)
+bool KOListView::ListItemVisitor::visit( Journal *j )
{
- static const TQPixmap jrnalPxmp = KOGlobals::self()->smallIcon( "journal" );
- mItem->setPixmap(0,jrnalPxmp);
+ static const TQPixmap jornalPxmp = KOGlobals::self()->smallIcon( "journal" );
+ mItem->setPixmap( Summary_Column, jornalPxmp );
// Just use the first line
- mItem->setText( 0, t->description().section( "\n", 0, 0 ) );
- mItem->setText( 3, t->dtStartDateStr() );
- mItem->setSortKey( 3, t->dtStart().toString(Qt::ISODate) );
+ mItem->setText( Summary_Column, j->description().section( "\n", 0, 0 ) );
+ mItem->setText( StartDateTime_Column, IncidenceFormatter::dateTimeToString( j->dtStart(), j->doesFloat() ) );
+ mItem->setSortKey( StartDateTime_Column, j->dtStart().toString( Qt::ISODate ) );
return true;
}
-KOListView::KOListView( Calendar *calendar, TQWidget *parent,
- const char *name)
- : KOEventView(calendar, parent, name)
+KOListView::KOListView( Calendar *calendar,
+ TQWidget *parent,
+ const char *name,
+ bool nonInteractive )
+ : KOEventView( calendar, parent, name )
{
mActiveItem = 0;
+ mIsNonInteractive = nonInteractive;
- mListView = new KListView(this);
- mListView->addColumn(i18n("Summary"));
- mListView->addColumn(i18n("Reminder")); // alarm set?
- mListView->addColumn(i18n("Recurs")); // recurs?
- mListView->addColumn(i18n("Start Date"));
- mListView->setColumnAlignment(3,AlignHCenter);
- mListView->addColumn(i18n("Start Time"));
- mListView->setColumnAlignment(4,AlignHCenter);
- mListView->addColumn(i18n("End Date"));
- mListView->setColumnAlignment(5,AlignHCenter);
- mListView->addColumn(i18n("End Time"));
- mListView->setColumnAlignment(6,AlignHCenter);
- mListView->addColumn(i18n("Categories"));
-
- TQBoxLayout *layoutTop = new TQVBoxLayout(this);
- layoutTop->addWidget(mListView);
+ mListView = new KListView( this );
+ mListView->addColumn( i18n("Summary") );
+ mListView->addColumn( i18n("Reminder") ); // alarm set?
+ mListView->setColumnAlignment( Reminder_Column, AlignHCenter );
+
+ mListView->addColumn( i18n("Recurs") ); // recurs?
+ mListView->setColumnAlignment( Recurs_Column, AlignHCenter );
+
+ mListView->addColumn( i18n("Start Date/Time") );
+ mListView->setColumnAlignment( StartDateTime_Column, AlignHCenter );
+
+ mListView->addColumn( i18n("End Date/Time") );
+ mListView->setColumnAlignment( EndDateTime_Column, AlignHCenter );
+
+ mListView->addColumn( i18n("Categories") );
+
+ TQBoxLayout *layoutTop = new TQVBoxLayout( this );
+ layoutTop->addWidget( mListView );
mPopupMenu = eventPopup();
/*
@@ -239,9 +244,9 @@ KOListView::KOListView( Calendar *calendar, TQWidget *parent,
TQT_SLOT( processSelectionChange() ) );
// setMinimumSize(100,100);
- mListView->restoreLayout(KOGlobals::self()->config(),"KOListView Layout");
+ mListView->restoreLayout( KOGlobals::self()->config(), "KOListView Layout" );
- new KOListViewToolTip( mListView->viewport(), mListView );
+ new KOListViewToolTip( mListView->viewport(), calendar, mListView );
mSelectedDates.append( TQDate::currentDate() );
}
@@ -266,43 +271,45 @@ Incidence::List KOListView::selectedIncidences()
Incidence::List eventList;
TQListViewItem *item = mListView->selectedItem();
- if (item) eventList.append(((KOListViewItem *)item)->data());
+ if ( item ) {
+ eventList.append( static_cast<KOListViewItem *>( item )->data() );
+ }
return eventList;
}
-DateList KOListView::selectedDates()
+DateList KOListView::selectedIncidenceDates()
{
return mSelectedDates;
}
-void KOListView::showDates(bool show)
+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);
+ 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->setColumnWidth( 1, oldColWidth1 );
+ mListView->setColumnWidth( 3, oldColWidth3 );
}
mListView->repaint();
}
void KOListView::showDates()
{
- showDates(true);
+ showDates( true );
}
void KOListView::hideDates()
{
- showDates(false);
+ showDates( false );
}
void KOListView::updateView()
@@ -310,82 +317,103 @@ void KOListView::updateView()
kdDebug(5850) << "KOListView::updateView() does nothing" << endl;
}
-void KOListView::showDates(const TQDate &start, const TQDate &end)
+void KOListView::showDates( const TQDate &start, const TQDate &end )
{
clear();
TQDate date = start;
while( date <= end ) {
- addIncidences( calendar()->incidences(date) );
+ addIncidences( calendar()->incidences( date ), date );
mSelectedDates.append( date );
date = date.addDays( 1 );
}
- emit incidenceSelected( 0 );
+ emit incidenceSelected( 0, TQDate() );
}
-void KOListView::addIncidences( const Incidence::List &incidenceList )
+void KOListView::showAll()
+{
+ Incidence::List incidenceList = calendar()->incidences();
+
+ Incidence::List::ConstIterator it;
+ for( it = incidenceList.begin(); it != incidenceList.end(); ++it ) {
+ // we don't need the date, using showAll in non interactive mode for now
+ addIncidence( *it, TQDate() );
+ }
+}
+
+void KOListView::addIncidences( const Incidence::List &incidenceList, const TQDate &date )
{
Incidence::List::ConstIterator it;
for( it = incidenceList.begin(); it != incidenceList.end(); ++it ) {
- addIncidence( *it );
+ addIncidence( *it, date );
}
}
-void KOListView::addIncidence(Incidence *incidence)
+void KOListView::addIncidence( Incidence *incidence, const TQDate &date )
{
- if ( mUidDict.find( incidence->uid() ) ) return;
+ if ( mUidDict.find( incidence->uid() ) ) {
+ return;
+ }
+ mDateList[incidence->uid()] = date;
mUidDict.insert( incidence->uid(), incidence );
KOListViewItem *item = new KOListViewItem( incidence, mListView );
- ListItemVisitor v(item);
- if (incidence->accept(v)) return;
- else delete item;
+ ListItemVisitor v( item );
+ if (incidence->accept( v ) ) {
+ return;
+ } else {
+ delete item;
+ }
}
-void KOListView::showIncidences( const Incidence::List &incidenceList )
+void KOListView::showIncidences( const Incidence::List &incidenceList, const TQDate &date )
{
clear();
- addIncidences( incidenceList );
+ addIncidences( incidenceList, date );
// After new creation of list view no events are selected.
- emit incidenceSelected( 0 );
+ emit incidenceSelected( 0, date );
}
-void KOListView::changeIncidenceDisplay(Incidence *incidence, int action)
+void KOListView::changeIncidenceDisplay( Incidence *incidence, int action )
{
KOListViewItem *item;
TQDate f = mSelectedDates.first();
TQDate l = mSelectedDates.last();
TQDate date;
- if ( incidence->type() == "Todo" )
- date = static_cast<Todo *>(incidence)->dtDue().date();
- else
+ if ( incidence->type() == "Todo" ) {
+ date = static_cast<Todo *>( incidence )->dtDue().date();
+ } else {
date = incidence->dtStart().date();
+ }
- switch(action) {
+ switch( action ) {
case KOGlobals::INCIDENCEADDED: {
if ( date >= f && date <= l )
- addIncidence( incidence );
+ addIncidence( incidence, date );
break;
}
case KOGlobals::INCIDENCEEDITED: {
- item = getItemForIncidence(incidence);
- if (item) {
+ item = getItemForIncidence( incidence );
+ if ( item ) {
delete item;
mUidDict.remove( incidence->uid() );
+ mDateList.remove( incidence->uid() );
+ }
+ if ( date >= f && date <= l ) {
+ addIncidence( incidence, date );
}
- if ( date >= f && date <= l )
- addIncidence( incidence );
}
break;
case KOGlobals::INCIDENCEDELETED: {
- item = getItemForIncidence(incidence);
- if (item)
+ item = getItemForIncidence( incidence );
+ if ( item ) {
delete item;
+ }
break;
}
default:
@@ -393,58 +421,68 @@ void KOListView::changeIncidenceDisplay(Incidence *incidence, int action)
}
}
-KOListViewItem *KOListView::getItemForIncidence(Incidence *incidence)
+KOListViewItem *KOListView::getItemForIncidence( Incidence *incidence )
{
- KOListViewItem *item = (KOListViewItem *)mListView->firstChild();
- while (item) {
+ KOListViewItem *item = static_cast<KOListViewItem *>( mListView->firstChild() );
+ while ( item ) {
// kdDebug(5850) << "Item " << item->text(0) << " found" << endl;
- if (item->data() == incidence) return item;
- item = (KOListViewItem *)item->nextSibling();
+ if ( item->data() == incidence ) {
+ return item;
+ }
+ item = static_cast<KOListViewItem *>( item->nextSibling() );
}
return 0;
}
-void KOListView::defaultItemAction(TQListViewItem *i)
+void KOListView::defaultItemAction( TQListViewItem *i )
{
- KOListViewItem *item = static_cast<KOListViewItem *>( i );
- if ( item ) defaultAction( item->data() );
+ if ( !mIsNonInteractive ) {
+ KOListViewItem *item = static_cast<KOListViewItem *>( i );
+ if ( item ) {
+ defaultAction( item->data() );
+ }
+ }
}
-void KOListView::popupMenu(TQListViewItem *item,const TQPoint &,int)
+void KOListView::popupMenu( TQListViewItem *item,const TQPoint &, int )
{
- mActiveItem = (KOListViewItem *)item;
- if (mActiveItem) {
- Incidence *incidence = mActiveItem->data();
- // FIXME: For recurring incidences we don't know the date of this
- // occurrence, there's no reference to it at all!
- mPopupMenu->showIncidencePopup( incidence, TQDate() );
- }
- else {
- showNewEventPopup();
+ if ( !mIsNonInteractive ) {
+ mActiveItem = static_cast<KOListViewItem *>( item );
+ if ( mActiveItem ) {
+ Incidence *incidence = mActiveItem->data();
+ // FIXME: For recurring incidences we don't know the date of this
+ // occurrence, there's no reference to it at all!
+ mPopupMenu->showIncidencePopup( calendar(), incidence, TQDate() );
+ } else {
+ showNewEventPopup();
+ }
}
}
-void KOListView::readSettings(KConfig *config)
+void KOListView::readSettings( KConfig *config )
{
- mListView->restoreLayout(config,"KOListView Layout");
+ mListView->restoreLayout( config,"KOListView Layout" );
}
-void KOListView::writeSettings(KConfig *config)
+void KOListView::writeSettings( KConfig *config )
{
- mListView->saveLayout(config,"KOListView Layout");
+ mListView->saveLayout( config, "KOListView Layout" );
}
void KOListView::processSelectionChange()
{
- kdDebug(5850) << "KOListView::processSelectionChange()" << endl;
+ if ( !mIsNonInteractive ) {
+ kdDebug(5850) << "KOListView::processSelectionChange()" << endl;
- KOListViewItem *item =
- static_cast<KOListViewItem *>( mListView->selectedItem() );
+ KOListViewItem *item =
+ static_cast<KOListViewItem *>( mListView->selectedItem() );
- if ( !item ) {
- emit incidenceSelected( 0 );
- } else {
- emit incidenceSelected( item->data() );
+ if ( !item ) {
+ emit incidenceSelected( 0, TQDate() );
+ } else {
+ Incidence *incidence = static_cast<Incidence *>( item->data() );
+ emit incidenceSelected( incidence, mDateList[incidence->uid()] );
+ }
}
}
@@ -458,4 +496,12 @@ void KOListView::clear()
mSelectedDates.clear();
mListView->clear();
mUidDict.clear();
+ mDateList.clear();
+}
+
+TQSize KOListView::sizeHint() const
+{
+ const TQSize s = KOEventView::sizeHint();
+ return TQSize( s.width() + style().pixelMetric( TQStyle::PM_ScrollBarExtent ) + 1,
+ s.height() );
}
diff --git a/korganizer/kolistview.h b/korganizer/kolistview.h
index 6da6988a..5a5c40d8 100644
--- a/korganizer/kolistview.h
+++ b/korganizer/kolistview.h
@@ -27,6 +27,7 @@
#define _KOLISTVIEW_H
#include <tqdict.h>
+#include <tqmap.h>
#include <tqtooltip.h>
#include <libkcal/incidence.h>
@@ -43,12 +44,13 @@ class KOListView;
class KOListViewToolTip : public QToolTip
{
public:
- KOListViewToolTip (TQWidget* parent, KListView* lv );
+ KOListViewToolTip ( TQWidget* parent, Calendar *calendar, KListView* lv );
protected:
- void maybeTip( const TQPoint & pos);
+ void maybeTip( const TQPoint &pos );
private:
+ Calendar *mCalendar;
KListView* eventlist;
};
@@ -67,26 +69,32 @@ class KOListView : public KOEventView
{
Q_OBJECT
public:
- KOListView(Calendar *calendar, TQWidget *parent = 0,
- const char *name = 0);
+ explicit KOListView( Calendar *calendar,
+ TQWidget *parent = 0,
+ const char *name = 0,
+ bool nonInteractive = false );
~KOListView();
virtual int maxDatesHint();
virtual int currentDateCount();
virtual Incidence::List selectedIncidences();
- virtual DateList selectedDates();
+ virtual DateList selectedIncidenceDates();
- void showDates(bool show);
+ void showDates( bool show );
+
+ // Shows all incidences of the calendar
+ void showAll();
void readSettings(KConfig *config);
void writeSettings(KConfig *config);
void clear();
+ TQSize sizeHint() const;
public slots:
virtual void updateView();
virtual void showDates( const TQDate &start, const TQDate &end );
- virtual void showIncidences( const Incidence::List &incidenceList );
+ virtual void showIncidences( const Incidence::List &incidenceList, const TQDate &date );
void clearSelection();
@@ -102,8 +110,8 @@ class KOListView : public KOEventView
void processSelectionChange();
protected:
- void addIncidences( const Incidence::List & );
- void addIncidence(Incidence *);
+ void addIncidences(const Incidence::List &, const TQDate &date);
+ void addIncidence(Incidence *, const TQDate &date);
KOListViewItem *getItemForIncidence(Incidence *incidence);
private:
@@ -112,7 +120,11 @@ class KOListView : public KOEventView
KOEventPopupMenu *mPopupMenu;
KOListViewItem *mActiveItem;
TQDict<Incidence> mUidDict;
+ TQMap<TQString, TQDate>mDateList;
DateList mSelectedDates;
+
+ // if it's non interactive we disable context menu, and incidence editing
+ bool mIsNonInteractive;
};
#endif
diff --git a/korganizer/komailclient.cpp b/korganizer/komailclient.cpp
index 946331fd..1b3215c0 100644
--- a/korganizer/komailclient.cpp
+++ b/korganizer/komailclient.cpp
@@ -34,12 +34,18 @@
#include <dcopclient.h>
#include <kprocess.h>
+#include <libemailfunctions/email.h>
+
+#include <libkpimidentities/identity.h>
+#include <libkpimidentities/identitymanager.h>
+
#include <libkcal/event.h>
#include <libkcal/todo.h>
#include <libkcal/incidenceformatter.h>
#include "version.h"
#include "koprefs.h"
+#include "kocore.h"
#include "komailclient.h"
@@ -54,23 +60,59 @@ KOMailClient::~KOMailClient()
bool KOMailClient::mailAttendees(IncidenceBase *incidence,const TQString &attachment)
{
Attendee::List attendees = incidence->attendees();
- if (attendees.count() == 0) return false;
+ if ( attendees.count() == 0 ) {
+ return false;
+ }
const TQString from = incidence->organizer().fullName();
const TQString organizerEmail = incidence->organizer().email();
+
TQStringList toList;
- for(uint i=0; i<attendees.count();++i) {
- const TQString email = (*attendees.at(i))->email();
- // In case we (as one of our identities) are the organizer we are sending this
- // mail. We could also have added ourselves as an attendee, in which case we
- // don't want to send ourselves a notification mail.
- if( organizerEmail != email )
- toList << email;
+ TQStringList ccList;
+ for ( uint i=0; i<attendees.count(); ++i ) {
+ Attendee *a = (*attendees.at(i));
+
+ const TQString email = a->email();
+ if ( email.isEmpty() ) {
+ continue;
+ }
+
+ // In case we (as one of our identities) are the organizer we are sending
+ // this mail. We could also have added ourselves as an attendee, in which
+ // case we don't want to send ourselves a notification mail.
+ if ( organizerEmail == email ) {
+ continue;
+ }
+
+ // Build a nice address for this attendee including the CN.
+ TQString tname, temail;
+ const TQString username = KPIM::quoteNameIfNecessary( a->name() );
+ KPIM::getNameAndMail( username, tname, temail ); // ignore return value
+ // which is always false
+ tname += " <" + email + '>';
+
+
+ // Optional Participants and Non-Participants are copied on the email
+ if ( a->role() == Attendee::OptParticipant ||
+ a->role() == Attendee::NonParticipant ) {
+ ccList << tname;
+ } else {
+ toList << tname;
+ }
}
- if( toList.count() == 0 )
+
+ if( toList.count() == 0 && ccList.count() == 0 ) {
// Not really to be called a groupware meeting, eh
return false;
- TQString to = toList.join( ", " );
+ }
+ TQString to;
+ if ( toList.count() > 0 ) {
+ to = toList.join( ", " );
+ }
+ TQString cc;
+ if ( ccList.count() > 0 ) {
+ cc = ccList.join( ", " );
+ }
TQString subject;
if(incidence->type()!="FreeBusy") {
@@ -84,7 +126,7 @@ bool KOMailClient::mailAttendees(IncidenceBase *incidence,const TQString &attach
bool bcc = KOPrefs::instance()->mBcc;
- return send(from,to,subject,body,bcc,attachment);
+ return send(from,to,cc,subject,body,bcc,attachment);
}
bool KOMailClient::mailOrganizer(IncidenceBase *incidence,const TQString &attachment, const TQString &sub)
@@ -106,7 +148,7 @@ bool KOMailClient::mailOrganizer(IncidenceBase *incidence,const TQString &attach
bool bcc = KOPrefs::instance()->mBcc;
- return send(from,to,subject,body,bcc,attachment);
+ return send(from,to,TQString::null,subject,body,bcc,attachment);
}
bool KOMailClient::mailTo(IncidenceBase *incidence,const TQString &recipients,
@@ -123,16 +165,25 @@ bool KOMailClient::mailTo(IncidenceBase *incidence,const TQString &recipients,
TQString body = IncidenceFormatter::mailBodyString(incidence);
bool bcc = KOPrefs::instance()->mBcc;
kdDebug () << "KOMailClient::mailTo " << recipients << endl;
- return send(from,recipients,subject,body,bcc,attachment);
+ return send(from,recipients,TQString::null,subject,body,bcc,attachment);
}
-bool KOMailClient::send(const TQString &from,const TQString &to,
+bool KOMailClient::send(const TQString &from,const TQString &_to,const TQString &cc,
const TQString &subject,const TQString &body,bool bcc,
const TQString &attachment)
{
- kdDebug(5850) << "KOMailClient::sendMail():\nFrom: " << from << "\nTo: " << to
- << "\nSubject: " << subject << "\nBody: \n" << body
- << "\nAttachment:\n" << attachment << endl;
+ // We must have a recipients list for most MUAs. Thus, if the 'to' list
+ // is empty simply use the 'from' address as the recipient.
+ TQString to = _to;
+ if ( to.isEmpty() ) {
+ to = from;
+ }
+
+ kdDebug(5850) << "KOMailClient::sendMail():\nFrom: " << from
+ << "\nTo: " << to
+ << "\nCC: " << cc
+ << "\nSubject: " << subject << "\nBody: \n" << body
+ << "\nAttachment:\n" << attachment << endl;
if (KOPrefs::instance()->mMailClient == KOPrefs::MailClientSendmail) {
bool needHeaders = true;
@@ -152,6 +203,11 @@ bool KOMailClient::send(const TQString &from,const TQString &to,
command.append(KProcess::quote(from));
}
+ if ( !cc.isEmpty() ) {
+ command.append(" -c ");
+ command.append(KProcess::quote(cc));
+ }
+
command.append(" ");
command.append(KProcess::quote(to));
@@ -170,6 +226,9 @@ bool KOMailClient::send(const TQString &from,const TQString &to,
{
textComplete += TQString::fromLatin1("From: ") + from + '\n';
textComplete += TQString::fromLatin1("To: ") + to + '\n';
+ if ( !cc.isEmpty() ) {
+ textComplete += TQString::fromLatin1("Cc: " ) + cc + '\n';
+ }
if (bcc) textComplete += TQString::fromLatin1("Bcc: ") + from + '\n';
textComplete += TQString::fromLatin1("Subject: ") + subject + '\n';
textComplete += TQString::fromLatin1("X-Mailer: KOrganizer") + korgVersion + '\n';
@@ -184,14 +243,14 @@ bool KOMailClient::send(const TQString &from,const TQString &to,
pclose(fd);
} else {
if (!kapp->dcopClient()->isApplicationRegistered("kmail")) {
- if (KApplication::startServiceByDesktopName("kmail")) {
+ if (KApplication::startServiceByDesktopName("kmail")) {
KMessageBox::error(0,i18n("No running instance of KMail found."));
return false;
- }
+ }
}
if (attachment.isEmpty()) {
- if (!kMailOpenComposer(to,"",bcc ? from : "",subject,body,0,KURL())) return false;
+ if (!kMailOpenComposer(to,cc,bcc ? from : "",subject,body,0,KURL())) return false;
} else {
TQString meth;
int idx = attachment.find("METHOD");
@@ -203,9 +262,12 @@ bool KOMailClient::send(const TQString &from,const TQString &to,
} else {
meth = "publish";
}
- if (!kMailOpenComposer(to,"",bcc ? from : "",subject,body,0,"cal.ics","7bit",
+ if (!kMailOpenComposer(to,cc,bcc ? from : "",subject,body,0,"cal.ics","7bit",
attachment.utf8(),"text","calendar","method",meth,
- "attachment","utf-8")) return false;
+ "attachment","utf-8",
+ KOCore::self()->identityManager()->identityForAddress( from ).uoid())) {
+ return false;
+ }
}
}
return true;
@@ -252,7 +314,7 @@ int KOMailClient::kMailOpenComposer( const TQString& arg0, const TQString& arg1,
const TQCString& arg7, const TQCString& arg8,
const TQCString& arg9, const TQCString& arg10,
const TQCString& arg11, const TQString& arg12,
- const TQCString& arg13, const TQCString& arg14 )
+ const TQCString& arg13, const TQCString& arg14, uint identity )
{
//kdDebug(5850) << "KOMailClient::kMailOpenComposer( "
// << arg0 << " , " << arg1 << arg2 << " , " << arg3
@@ -281,11 +343,12 @@ int KOMailClient::kMailOpenComposer( const TQString& arg0, const TQString& arg1,
arg << arg12;
arg << arg13;
arg << arg14;
+ arg << identity;
#if KDE_IS_VERSION( 3, 2, 90 )
kapp->updateRemoteUserTimestamp("kmail");
#endif
if ( kapp->dcopClient()->call("kmail","KMailIface",
- "openComposer(TQString,TQString,TQString,TQString,TQString,int,TQString,TQCString,TQCString,TQCString,TQCString,TQCString,TQString,TQCString,TQCString)", data, replyType, replyData ) ) {
+ "openComposer(TQString,TQString,TQString,TQString,TQString,int,TQString,TQCString,TQCString,TQCString,TQCString,TQCString,TQString,TQCString,TQCString,uint)", data, replyType, replyData ) ) {
if ( replyType == "int" ) {
TQDataStream _reply_stream( replyData, IO_ReadOnly );
_reply_stream >> result;
diff --git a/korganizer/komailclient.h b/korganizer/komailclient.h
index da71ecec..3051bab7 100644
--- a/korganizer/komailclient.h
+++ b/korganizer/komailclient.h
@@ -45,8 +45,8 @@ class KOMailClient
protected:
/** Send mail with specified from, to and subject field and body as text. If
* bcc is set, send a blind carbon copy to the sender from */
- bool send(const TQString &from,const TQString &to,const TQString &subject,
- const TQString &body,bool bcc=false,
+ bool send(const TQString &from,const TQString &to,const TQString &cc,
+ const TQString &subject,const TQString &body,bool bcc=false,
const TQString &attachment=TQString::null);
int kMailOpenComposer(const TQString& to, const TQString& cc,
@@ -59,7 +59,8 @@ class KOMailClient
const TQCString& attachParamAttr,
const TQString& attachParamValue,
const TQCString& attachContDisp,
- const TQCString& attachCharset);
+ const TQCString& attachCharset,
+ uint identity);
int kMailOpenComposer(const TQString& arg0,const TQString& arg1,
const TQString& arg2,const TQString& arg3,
const TQString& arg4,int arg5,const KURL& arg6);
diff --git a/korganizer/komonthview.cpp b/korganizer/komonthview.cpp
index 85d9049b..26452541 100644
--- a/korganizer/komonthview.cpp
+++ b/korganizer/komonthview.cpp
@@ -62,13 +62,15 @@
//--------------------------------------------------------------------------
KOMonthCellToolTip::KOMonthCellToolTip( TQWidget *parent,
+ Calendar *calendar,
+ const TQDate &date,
KNoScrollListBox *lv )
- : TQToolTip( parent )
+ : TQToolTip( parent ), mCalendar( calendar ), mDate( date )
{
eventlist = lv;
}
-void KOMonthCellToolTip::maybeTip( const TQPoint & pos )
+void KOMonthCellToolTip::maybeTip( const TQPoint &pos )
{
TQRect r;
TQListBoxItem *it = eventlist->itemAt( pos );
@@ -78,7 +80,7 @@ void KOMonthCellToolTip::maybeTip( const TQPoint & pos )
/* Calculate the rectangle. */
r=eventlist->itemRect( it );
/* Show the tip */
- TQString tipText( IncidenceFormatter::toolTipString( i->incidence() ) );
+ TQString tipText( IncidenceFormatter::toolTipStr( mCalendar, i->incidence(), mDate ) );
if ( !tipText.isEmpty() ) {
tip( r, tipText );
}
@@ -199,13 +201,14 @@ MonthViewItem::MonthViewItem( Incidence *incidence, const TQDateTime &qd,
mDateTime = qd;
mEventPixmap = KOGlobals::self()->smallIcon( "appointment" );
+ mBirthdayPixmap = KOGlobals::self()->smallIcon( "calendarbirthday" );
+ mAnniversaryPixmap= KOGlobals::self()->smallIcon( "calendaranniversary" );
mTodoPixmap = KOGlobals::self()->smallIcon( "todo" );
mTodoDonePixmap = KOGlobals::self()->smallIcon( "checkedbox" );
mAlarmPixmap = KOGlobals::self()->smallIcon( "bell" );
mRecurPixmap = KOGlobals::self()->smallIcon( "recur" );
mReplyPixmap = KOGlobals::self()->smallIcon( "mail_reply" );
- mResourceColor = TQColor();
mEvent = false;
mTodo = false;
mTodoDone = false;
@@ -214,6 +217,26 @@ MonthViewItem::MonthViewItem( Incidence *incidence, const TQDateTime &qd,
mReply = false;
}
+TQColor MonthViewItem::catColor() const
+{
+ TQColor retColor;
+ if ( !mIncidence ) {
+ return retColor;
+ }
+
+ TQStringList categories = mIncidence->categories();
+ TQString cat;
+ if ( !categories.isEmpty() ) {
+ cat = categories.first();
+ }
+ if ( cat.isEmpty() ) {
+ retColor = KOPrefs::instance()->unsetCategoryColor();
+ } else {
+ retColor = *( KOPrefs::instance()->categoryColor( cat ) );
+ }
+ return retColor;
+}
+
void MonthViewItem::paint( TQPainter *p )
{
#if QT_VERSION >= 0x030000
@@ -222,25 +245,86 @@ void MonthViewItem::paint( TQPainter *p )
bool sel = selected();
#endif
- TQColor bgColor = palette().color( TQPalette::Normal,
- sel ? TQColorGroup::Highlight : TQColorGroup::Background );
- int offset=0;
- if ( KOPrefs::instance()->monthViewUsesResourceColor() &&
- mResourceColor.isValid() ) {
- p->setBackgroundColor( mResourceColor );
- p->eraseRect( 0, 0, listBox()->maxItemWidth(), height( listBox() ) );
- offset=2;
+ TQColor bgColor = TQColor(); // Default invalid color;
+ if ( mIncidence && mTodo ) {
+ if ( static_cast<Todo*>( mIncidence )->isOverdue() ) {
+ bgColor = KOPrefs::instance()->todoOverdueColor();
+ } else if ( static_cast<Todo*>( mIncidence )->dtDue().date() == TQDate::currentDate() ) {
+ bgColor = KOPrefs::instance()->todoDueTodayColor();
+ }
+ }
+
+ if ( !bgColor.isValid() ) {
+ if ( KOPrefs::instance()->monthItemColors() == KOPrefs::MonthItemResourceOnly ||
+ KOPrefs::instance()->monthItemColors() == KOPrefs::MonthItemResourceInsideCategoryOutside ) {
+ bgColor = resourceColor();
+ } else {
+ bgColor = catColor();
+ }
+
+ if ( !bgColor.isValid() ) {
+ bgColor = palette().color( TQPalette::Normal,
+ sel ? TQColorGroup::Highlight :
+ TQColorGroup::Background );
+ }
+ }
+
+ TQColor frameColor;
+ if ( KOPrefs::instance()->monthItemColors() == KOPrefs::MonthItemResourceOnly ||
+ KOPrefs::instance()->monthItemColors() == KOPrefs::MonthItemCategoryInsideResourceOutside ) {
+ frameColor = resourceColor();
+ } else {
+ frameColor = catColor();
+ }
+
+ if ( mIncidence ) {
+ if ( mIncidence->categories().isEmpty() &&
+ KOPrefs::instance()->monthItemColors() == KOPrefs::MonthItemResourceInsideCategoryOutside ) {
+ frameColor = bgColor;
+ }
+
+ if ( mIncidence->categories().isEmpty() &&
+ KOPrefs::instance()->monthItemColors() == KOPrefs::MonthItemCategoryInsideResourceOutside ) {
+ bgColor = frameColor;
+ }
}
- if ( KOPrefs::instance()->monthViewUsesCategoryColor() ) {
- p->setBackgroundColor( bgColor );
- p->eraseRect( offset, offset, listBox()->maxItemWidth()-2*offset, height( listBox() )-2*offset );
+
+ if ( !frameColor.isValid() ) {
+ frameColor = palette().color( TQPalette::Normal,
+ sel ? TQColorGroup::Highlight :
+ TQColorGroup::Foreground );
+ } else {
+ frameColor = frameColor.dark( 115 );
}
+
+ // draw the box for the item
+ p->setBackgroundColor( frameColor );
+ p->eraseRect( 0, 0, listBox()->maxItemWidth(), height( listBox() ) );
+ int offset = 2;
+ p->setBackgroundColor( bgColor );
+ p->eraseRect( offset, offset, listBox()->maxItemWidth()-2*offset, height( listBox() )-2*offset );
+
int x = 3;
-// Do NOT put on the event pixmap because it takes up too much space
-// if ( mEvent ) {
-// p->drawPixmap( x, 0, mEventPixmap );
-// x += mEventPixmap.width() + 2;
-// }
+
+ bool specialEvent = false;
+ if ( mEvent ) {
+ if ( mIncidence->customProperty( "KABC", "BIRTHDAY" ) == "YES" ) {
+ specialEvent = true;
+ if ( mIncidence->customProperty( "KABC", "ANNIVERSARY" ) == "YES" ) {
+ p->drawPixmap( x, 0, mAnniversaryPixmap );
+ x += mAnniversaryPixmap.width() + 2;
+ } else {
+ p->drawPixmap( x, 0, mBirthdayPixmap );
+ x += mBirthdayPixmap.width() + 2;
+ }
+ // Do NOT put on the event pixmap because it takes up too much space
+ //} else {
+ // p->drawPixmap( x, 0, mEventPixmap );
+ // x += mEventPixmap.width() + 2;
+ //
+ }
+ }
+
if ( mTodo ) {
p->drawPixmap( x, 0, mTodoPixmap );
x += mTodoPixmap.width() + 2;
@@ -249,11 +333,11 @@ void MonthViewItem::paint( TQPainter *p )
p->drawPixmap( x, 0, mTodoDonePixmap );
x += mTodoPixmap.width() + 2;
}
- if ( mRecur ) {
+ if ( mRecur && !specialEvent ) {
p->drawPixmap( x, 0, mRecurPixmap );
x += mRecurPixmap.width() + 2;
}
- if ( mAlarm ) {
+ if ( mAlarm && !specialEvent ) {
p->drawPixmap( x, 0, mAlarmPixmap );
x += mAlarmPixmap.width() + 2;
}
@@ -300,7 +384,8 @@ int MonthViewItem::width( const TQListBox *lb ) const
MonthViewCell::MonthViewCell( KOMonthView *parent)
: TQWidget( parent ),
- mMonthView( parent ), mPrimary( false ), mHoliday( false )
+ mMonthView( parent ), mPrimary( false ), mHoliday( false ),
+ isSelected( false )
{
TQVBoxLayout *topLayout = new TQVBoxLayout( this );
@@ -314,9 +399,6 @@ MonthViewCell::MonthViewCell( KOMonthView *parent)
mItemList->setFrameStyle( TQFrame::Panel | TQFrame::Plain );
mItemList->setLineWidth( 1 );
- new KOMonthCellToolTip( mItemList->viewport(),
- static_cast<KNoScrollListBox *>( mItemList ) );
-
topLayout->addWidget( mItemList );
mLabel->raise();
@@ -357,6 +439,11 @@ void MonthViewCell::setDate( const TQDate &date )
}
mLabel->setText( text );
+ new KOMonthCellToolTip( mItemList->viewport(),
+ monthView()->calendar(),
+ mDate,
+ static_cast<KNoScrollListBox *>( mItemList ) );
+
resizeEvent( 0 );
}
@@ -368,10 +455,11 @@ TQDate MonthViewCell::date() const
void MonthViewCell::setFrameWidth()
{
// show current day with a thicker frame
- if ( mDate == TQDate::currentDate() )
+ if ( mDate == TQDate::currentDate() ) {
mItemList->setLineWidth( 3 );
- else
+ } else if ( !isSelected ) {
mItemList->setLineWidth( 1 );
+ }
}
void MonthViewCell::setPrimary( bool primary )
@@ -490,13 +578,16 @@ class MonthViewCell::CreateItemVisitor :
mItem = new MonthViewItem( event, dt, text );
mItem->setEvent( true );
- if (KOPrefs::instance()->monthViewUsesCategoryColor()) {
+ if ( KOPrefs::instance()->monthItemColors() == KOPrefs::MonthItemCategoryOnly ||
+ KOPrefs::instance()->monthItemColors() == KOPrefs::MonthItemCategoryInsideResourceOutside ) {
TQStringList categories = event->categories();
TQString cat = categories.first();
if (cat.isEmpty()) {
- mItem->setPalette(TQPalette(KOPrefs::instance()->mEventColor, KOPrefs::instance()->mEventColor));
+ mItem->setPalette(TQPalette(KOPrefs::instance()->unsetCategoryColor(),
+ KOPrefs::instance()->unsetCategoryColor()) );
} else {
- mItem->setPalette(TQPalette(*(KOPrefs::instance()->categoryColor(cat)), *(KOPrefs::instance()->categoryColor(cat))));
+ mItem->setPalette(TQPalette(*(KOPrefs::instance()->categoryColor(cat)),
+ *(KOPrefs::instance()->categoryColor(cat))));
}
} else {
mItem->setPalette( mStandardPalette );
@@ -514,7 +605,8 @@ class MonthViewCell::CreateItemVisitor :
if ( !KOPrefs::instance()->showAllDayTodo() )
return false;
TQDateTime dt( mDate );
- if ( todo->hasDueDate() && !todo->doesFloat() ) {
+ if ( todo->hasDueDate() && !todo->doesFloat() &&
+ todo->dtDue().time() != TQTime( 0,0 ) && todo->dtDue().time().isValid() ) {
text += KGlobal::locale()->formatTime( todo->dtDue().time() );
text += ' ';
dt.setTime( todo->dtDue().time() );
@@ -547,9 +639,9 @@ void MonthViewCell::addIncidence( Incidence *incidence, CreateItemVisitor& v, in
item->setAlarm( incidence->isAlarmEnabled() );
item->setRecur( incidence->recurrenceType() );
- TQColor resourceColor = KOHelper::resourceColor( mCalendar, incidence );
+ TQColor resourceColor = KOHelper::resourceColor( monthView()->calendar(), incidence );
if ( !resourceColor.isValid() )
- resourceColor = KOPrefs::instance()->mEventColor;
+ resourceColor = KOPrefs::instance()->unsetCategoryColor();
item->setResourceColor( resourceColor );
// FIXME: Find the correct position (time-wise) to insert the item.
@@ -661,6 +753,9 @@ TQDate MonthViewCell::selectedIncidenceDate()
void MonthViewCell::select()
{
+
+ isSelected = true;
+
// setSelectedCell will deselect currently selected cells
mMonthView->setSelectedCell( this );
@@ -676,6 +771,8 @@ void MonthViewCell::select()
void MonthViewCell::deselect()
{
+ isSelected = false;
+
mItemList->clearSelection();
mItemList->setFrameStyle( TQFrame::Plain | TQFrame::Panel );
setFrameWidth();
@@ -693,7 +790,7 @@ void MonthViewCell::defaultAction( TQListBoxItem *item )
select();
if ( !item ) {
- emit newEventSignal( date() );
+ emit newEventSignal( 0/*ResourceCalendar*/, TQString()/*subResource*/, date() );
} else {
MonthViewItem *eventItem = static_cast<MonthViewItem *>( item );
Incidence *incidence = eventItem->incidence();
@@ -708,9 +805,10 @@ void MonthViewCell::contextMenu( TQListBoxItem *item )
if ( item ) {
MonthViewItem *eventItem = static_cast<MonthViewItem *>( item );
Incidence *incidence = eventItem->incidence();
- if ( incidence ) mMonthView->showEventContextMenu( incidence, date() );
- }
- else {
+ if ( incidence ) {
+ mMonthView->showEventContextMenu( monthView()->calendar(), incidence, mDate );
+ }
+ } else {
mMonthView->showGeneralContextMenu();
}
}
@@ -764,14 +862,13 @@ KOMonthView::KOMonthView( Calendar *calendar, TQWidget *parent, const char *name
for( row = 0; row < mNumWeeks; ++row ) {
for( col = 0; col < mDaysPerWeek; ++col ) {
MonthViewCell *cell = new MonthViewCell( this );
- cell->setCalendar(calendar);
mCells.insert( row * mDaysPerWeek + col, cell );
dayLayout->addWidget( cell, row + 2, col );
- connect( cell, TQT_SIGNAL( defaultAction( Incidence * ) ),
- TQT_SLOT( defaultAction( Incidence * ) ) );
- connect( cell, TQT_SIGNAL( newEventSignal( const TQDate & ) ),
- TQT_SIGNAL( newEventSignal( const TQDate & ) ) );
+ connect( cell, TQT_SIGNAL(defaultAction(Incidence *)),
+ TQT_SLOT(defaultAction(Incidence *)) );
+ connect( cell, TQT_SIGNAL(newEventSignal(ResourceCalendar *,const TQString &,const TQDate &)),
+ TQT_SIGNAL(newEventSignal(ResourceCalendar *,const TQString &,const TQDate &)) );
}
dayLayout->setRowStretch( row + 2, 1 );
}
@@ -780,7 +877,7 @@ KOMonthView::KOMonthView( Calendar *calendar, TQWidget *parent, const char *name
updateConfig();
- emit incidenceSelected( 0 );
+ emit incidenceSelected( 0, TQDate() );
}
KOMonthView::~KOMonthView()
@@ -810,7 +907,7 @@ Incidence::List KOMonthView::selectedIncidences()
return selected;
}
-DateList KOMonthView::selectedDates()
+DateList KOMonthView::selectedIncidenceDates()
{
DateList selected;
@@ -851,6 +948,8 @@ void KOMonthView::updateConfig()
for ( uint i = 0; i < mCells.count(); ++i ) {
mCells[i]->updateConfig();
}
+
+ showLabel( !KOPrefs::instance()->fullViewMonth() );
}
void KOMonthView::updateDayLabels()
@@ -883,11 +982,8 @@ void KOMonthView::showDates( const TQDate &start, const TQDate & )
mLabel->setText( i18n( "monthname year", "%1 %2" )
.arg( calSys->monthName( start ) )
.arg( calSys->year( start ) ) );
- if ( !KOPrefs::instance()->fullViewMonth() ) {
- mLabel->show();
- } else {
- mLabel->hide();
- }
+
+ showLabel( !KOPrefs::instance()->fullViewMonth() );
bool primary = false;
uint i;
@@ -899,8 +995,9 @@ void KOMonthView::showDates( const TQDate &start, const TQDate & )
mCells[i]->setDate( date );
mDateToCell[ date ] = mCells[ i ];
- if( date == start )
+ if( date == start ) {
mCells[i]->select();
+ }
mCells[i]->setPrimary( primary );
@@ -916,7 +1013,22 @@ void KOMonthView::showDates( const TQDate &start, const TQDate & )
updateView();
}
-void KOMonthView::showIncidences( const Incidence::List & )
+TQDateTime KOMonthView::selectionStart()
+{
+ if ( mSelectedCell) {
+ return TQDateTime( mSelectedCell->date() );
+ } else {
+ return TQDateTime();
+ }
+}
+
+TQDateTime KOMonthView::selectionEnd()
+{
+ // Only one cell can be selected (for now)
+ return selectionStart();
+}
+
+void KOMonthView::showIncidences( const Incidence::List &, const TQDate & )
{
kdDebug(5850) << "KOMonthView::showIncidences( const Incidence::List & ) is not implemented yet." << endl;
}
@@ -941,8 +1053,14 @@ class KOMonthView::GetDateVisitor : public IncidenceBase::Visitor
}
bool visit( Todo *todo ) {
if ( todo->hasDueDate() ) {
- mStartDate = todo->dtDue();
- mEndDate = todo->dtDue();
+ if ( todo->dtDue().time() != TQTime( 0, 0 ) &&
+ todo->dtDue().time().isValid() ) {
+ mStartDate = todo->dtDue();
+ mEndDate = todo->dtDue();
+ } else {
+ mStartDate = TQDateTime( todo->dtDue().date(), TQTime( 23,59 ) );
+ mEndDate = mStartDate;
+ }
}// else
// return false;
return true;
@@ -1048,9 +1166,9 @@ void KOMonthView::resizeEvent( TQResizeEvent * )
}
}
-void KOMonthView::showEventContextMenu( Incidence *incidence, const TQDate &qd )
+void KOMonthView::showEventContextMenu( Calendar *cal, Incidence *incidence, const TQDate &qd )
{
- mEventContextMenu->showIncidencePopup( incidence, qd );
+ mEventContextMenu->showIncidencePopup( cal, incidence, qd );
}
void KOMonthView::showGeneralContextMenu()
@@ -1066,18 +1184,26 @@ void KOMonthView::setSelectedCell( MonthViewCell *cell )
mSelectedCell = cell;
if ( !mSelectedCell )
- emit incidenceSelected( 0 );
+ emit incidenceSelected( 0, TQDate() );
else
- emit incidenceSelected( mSelectedCell->selectedIncidence() );
+ if ( selectedIncidenceDates().isEmpty() ) {
+ emit incidenceSelected( mSelectedCell->selectedIncidence(), TQDate() );
+ } else {
+ emit incidenceSelected( mSelectedCell->selectedIncidence(), selectedIncidenceDates().first() );
+ }
}
void KOMonthView::processSelectionChange()
{
Incidence::List incidences = selectedIncidences();
if (incidences.count() > 0) {
- emit incidenceSelected( incidences.first() );
+ if ( selectedIncidenceDates().isEmpty() ) {
+ emit incidenceSelected( incidences.first(), TQDate() );
+ } else {
+ emit incidenceSelected( incidences.first(), selectedIncidenceDates().first() );
+ }
} else {
- emit incidenceSelected( 0 );
+ emit incidenceSelected( 0, TQDate() );
}
}
@@ -1088,3 +1214,12 @@ void KOMonthView::clearSelection()
mSelectedCell = 0;
}
}
+
+void KOMonthView::showLabel( bool show )
+{
+ if ( show ) {
+ mLabel->show();
+ } else {
+ mLabel->hide();
+ }
+}
diff --git a/korganizer/komonthview.h b/korganizer/komonthview.h
index 9a3015d0..dafce597 100644
--- a/korganizer/komonthview.h
+++ b/korganizer/komonthview.h
@@ -36,12 +36,14 @@ class KNoScrollListBox;
class KOMonthCellToolTip : public QToolTip
{
public:
- KOMonthCellToolTip (TQWidget* parent, KNoScrollListBox* lv );
+ KOMonthCellToolTip (TQWidget* parent, Calendar *calendar, const TQDate &date, KNoScrollListBox* lv );
protected:
void maybeTip( const TQPoint & pos);
private:
+ Calendar *mCalendar;
+ TQDate mDate;
KNoScrollListBox* eventlist;
};
@@ -107,6 +109,8 @@ class MonthViewItem: public QListBoxItem
bool mReply;
TQPixmap mEventPixmap;
+ TQPixmap mBirthdayPixmap;
+ TQPixmap mAnniversaryPixmap;
TQPixmap mTodoPixmap;
TQPixmap mTodoDonePixmap;
TQPixmap mAlarmPixmap;
@@ -117,6 +121,7 @@ class MonthViewItem: public QListBoxItem
TQDateTime mDateTime;
Incidence *mIncidence;
+ TQColor catColor() const;
};
@@ -138,6 +143,9 @@ class MonthViewCell : public QWidget
/** @return Date of cell */
TQDate date() const;
+ /** @return MonthView parent */
+ KOMonthView *monthView() { return mMonthView; }
+
/**
Set this cell as primary if @p primary is true. A primary cell belongs
to the current month. A non-primary cell belongs to the month before or
@@ -184,7 +192,6 @@ class MonthViewCell : public QWidget
void deselect();
- void setCalendar( Calendar*cal ) { mCalendar = cal; }
signals:
void defaultAction( Incidence * );
/**
@@ -192,7 +199,8 @@ class MonthViewCell : public QWidget
will pop up.
@param date The date of the event we want create.
*/
- void newEventSignal( const TQDate &date );
+ void newEventSignal( ResourceCalendar *res,const TQString &subResource,
+ const TQDate &date );
public slots:
void select();
@@ -207,8 +215,6 @@ class MonthViewCell : public QWidget
private:
KOMonthView *mMonthView;
- // We need the calendar for paint the ResourceColor
- Calendar *mCalendar;
TQDate mDate;
bool mPrimary;
@@ -218,6 +224,8 @@ class MonthViewCell : public QWidget
TQLabel *mLabel;
KNoScrollListBox *mItemList;
+ bool isSelected;
+
TQSize mLabelSize;
// TQPalette mOriginalPalette;
TQPalette mHolidayPalette;
@@ -249,7 +257,11 @@ class KOMonthView: public KOEventView
virtual Incidence::List selectedIncidences();
/** Returns dates of the currently selected events */
- virtual DateList selectedDates();
+ virtual DateList selectedIncidenceDates();
+
+ virtual TQDateTime selectionStart();
+
+ virtual TQDateTime selectionEnd();
virtual bool eventDurationHint(TQDateTime &startDt, TQDateTime &endDt, bool &allDay);
@@ -257,14 +269,14 @@ class KOMonthView: public KOEventView
virtual void updateView();
virtual void updateConfig();
virtual void showDates(const TQDate &start, const TQDate &end);
- virtual void showIncidences( const Incidence::List &incidenceList );
+ virtual void showIncidences( const Incidence::List &incidenceList, const TQDate &date );
void changeIncidenceDisplay(Incidence *, int);
void changeIncidenceDisplayAdded(Incidence *, MonthViewCell::CreateItemVisitor&);
void clearSelection();
- void showEventContextMenu( Incidence *, const TQDate & );
+ void showEventContextMenu( Calendar *, Incidence *, const TQDate & );
void showGeneralContextMenu();
void setSelectedCell( MonthViewCell * );
@@ -279,6 +291,8 @@ class KOMonthView: public KOEventView
void updateDayLabels();
private:
+ void showLabel( bool show );
+
class GetDateVisitor;
int mDaysPerWeek;
int mNumWeeks;
diff --git a/korganizer/koprefs.cpp b/korganizer/koprefs.cpp
index 3532b1cc..535fe104 100644
--- a/korganizer/koprefs.cpp
+++ b/korganizer/koprefs.cpp
@@ -88,12 +88,9 @@ KOPrefs::KOPrefs() :
timeBarFontItem()->setDefaultValue( mDefaultTimeBarFont );
monthViewFontItem()->setDefaultValue( mDefaultMonthViewFont );
- eventColorItem()->setDefaultValue( mDefaultCategoryColor );
// Load it now, not deep within some painting code
mMyAddrBookMails = KABC::StdAddressBook::self()->whoAmI().emails();
-
- mAlarmsEnabledByDefault = false;
}
@@ -202,8 +199,8 @@ void KOPrefs::usrReadConfig()
TQMapIterator<TQString, TQString> it3;
for( it3 = map.begin(); it3 != map.end(); ++it3 ) {
- kdDebug(5850)<< "KOPrefs::usrReadConfig: key: " << it3.key() << " value: "
- << it3.data()<<endl;
+ // kdDebug(5850)<< "KOPrefs::usrReadConfig: key: " << it3.key() << " value: "
+ // << it3.data()<<endl;
setResourceColor( it3.key(), config()->readColorEntry( it3.key(),
&mDefaultResourceColor ) );
}
@@ -213,9 +210,6 @@ void KOPrefs::usrReadConfig()
setTimeZoneIdDefault();
}
- config()->setGroup("Event Dialogs");
- mAlarmsEnabledByDefault = config()->readBoolEntry( "Alarm Enabled By Default" );
-
#if 0
config()->setGroup("FreeBusy");
if( mRememberRetrievePw )
@@ -256,9 +250,6 @@ void KOPrefs::usrWriteConfig()
i->writeConfig( config() );
}
- config()->setGroup("Event Dialogs");
- config()->writeEntry( "Alarm Enabled By Default", mAlarmsEnabledByDefault );
-
#if 0
if( mRememberRetrievePw )
config()->writeEntry( "Retrieve Server Password", KStringHandler::obscure( mRetrievePassword ) );
@@ -292,8 +283,8 @@ bool KOPrefs::hasCategoryColor( const TQString& cat ) const
void KOPrefs::setResourceColor ( const TQString &cal, const TQColor &color )
{
- kdDebug(5850)<<"KOPrefs::setResourceColor: " << cal << " color: "<<
- color.name()<<endl;
+ // kdDebug(5850)<<"KOPrefs::setResourceColor: " << cal << " color: "<<
+ // color.name()<<endl;
mResourceColors.replace( cal, new TQColor( color ) );
}
@@ -327,12 +318,21 @@ TQColor* KOPrefs::resourceColor( const TQString &cal )
TQString KOPrefs::fullName()
{
+ TQString tusername;
if ( mEmailControlCenter ) {
KEMailSettings settings;
- return settings.getSetting( KEMailSettings::RealName );
+ tusername = settings.getSetting( KEMailSettings::RealName );
} else {
- return userName();
+ tusername = userName();
}
+
+ // Quote the username as it might contain commas and other quotable chars.
+ tusername = KPIM::quoteNameIfNecessary( tusername );
+
+ TQString tname, temail;
+ KPIM::getNameAndMail( tusername, tname, temail ); // ignore return value
+ // which is always false
+ return tname;
}
TQString KOPrefs::email()
@@ -415,8 +415,11 @@ bool KOPrefs::thatIsMe( const TQString& _email )
for ( KPIM::IdentityManager::ConstIterator it = KOCore::self()->identityManager()->begin();
it != KOCore::self()->identityManager()->end(); ++it ) {
- if ( email == (*it).emailAddr() )
+ if ( email == (*it).primaryEmailAddress() )
return true;
+ const TQStringList & aliases = (*it).emailAliases();
+ if ( aliases.find( email ) != aliases.end() )
+ return true;
}
if ( mAdditionalMails.find( email ) != mAdditionalMails.end() )
diff --git a/korganizer/koprefs.h b/korganizer/koprefs.h
index 48a42cbd..fcda7143 100644
--- a/korganizer/koprefs.h
+++ b/korganizer/koprefs.h
@@ -91,7 +91,6 @@ class KDE_EXPORT KOPrefs : public KOPrefsBase
TQColor* resourceColor( const TQString & );
TQString mHtmlExportFile;
- bool mAlarmsEnabledByDefault;
// Groupware passwords
TQString mPublishPassword;
diff --git a/korganizer/koprefsdialog.cpp b/korganizer/koprefsdialog.cpp
index 0205b59e..37f889cf 100644
--- a/korganizer/koprefsdialog.cpp
+++ b/korganizer/koprefsdialog.cpp
@@ -44,20 +44,24 @@
#include <tqwhatsthis.h>
#include <kcolorbutton.h>
+#include <kcombobox.h>
#include <kdebug.h>
#include <klocale.h>
#include <kglobal.h>
#include <kmessagebox.h>
#include <kiconloader.h>
+#include <knuminput.h>
#include <kemailsettings.h>
#include <kcalendarsystem.h>
#include <ktrader.h>
#include <kpushbutton.h>
#include <kocore.h>
-#include <libkcal/calendarresources.h>
#include <kstandarddirs.h>
#include <ksimpleconfig.h>
#include <kholidays.h>
+#include <kurlrequester.h>
+
+#include <libkcal/calendarresources.h>
#if defined(USE_SOLARIS)
#include <sys/param.h>
@@ -315,21 +319,46 @@ class KOPrefsDialogTime : public KPrefsModule
topLayout->addWidget( defaultDuration->label(), 4, 0 );
topLayout->addWidget( defaultDuration->timeEdit(), 4, 1 );
- TQStringList alarmList;
- alarmList << i18n( "1 minute" ) << i18n( "5 minutes" )
- << i18n( "10 minutes" ) << i18n( "15 minutes" )
- << i18n( "30 minutes" );
- TQLabel *alarmLabel = new TQLabel( i18n( "Default reminder time:" ), topFrame);
- topLayout->addWidget( alarmLabel, 5, 0 );
- TQWhatsThis::add( alarmLabel,
- i18n( "Enter the default reminder time here." ) );
- mAlarmTimeCombo = new TQComboBox( topFrame );
- TQWhatsThis::add( mAlarmTimeCombo,
- i18n( "Enter the default reminder time here." ) );
- connect( mAlarmTimeCombo, TQT_SIGNAL( activated( int ) ),
- TQT_SLOT( slotWidChanged() ) );
- mAlarmTimeCombo->insertStringList( alarmList );
- topLayout->addWidget( mAlarmTimeCombo, 5, 1 );
+ TQGroupBox *remindersGroupBox = new TQGroupBox( 1, Horizontal,
+ i18n( "Reminders" ),
+ topFrame );
+ topLayout->addMultiCellWidget( remindersGroupBox, 5, 5, 0, 1 );
+
+ TQHBox *remindersBox = new TQHBox( remindersGroupBox );
+ new TQLabel( i18n( "Default reminder time:" ), remindersBox );
+
+ mReminderTimeSpin = new KIntSpinBox( remindersBox );
+ connect( mReminderTimeSpin, TQT_SIGNAL(valueChanged(int)), TQT_SLOT(slotWidChanged()) );
+
+ mReminderUnitsCombo = new KComboBox( remindersBox );
+ connect( mReminderUnitsCombo, TQT_SIGNAL(activated(int)), TQT_SLOT(slotWidChanged()) );
+ mReminderUnitsCombo->insertItem( i18n( "minute(s)" ) );
+ mReminderUnitsCombo->insertItem( i18n( "hour(s)" ) );
+ mReminderUnitsCombo->insertItem( i18n( "day(s)" ) );
+
+ TQHBox *audioFileRemindersBox = new TQHBox( remindersGroupBox );
+
+ TQCheckBox *cb = addWidBool( KOPrefs::instance()->defaultAudioFileRemindersItem(),
+ audioFileRemindersBox )->checkBox();
+ cb->setText( TQString::null );
+
+ if ( KOPrefs::instance()->audioFilePathItem()->value().isEmpty() ) {
+ TQString defAudioFile = KGlobal::dirs()->findResourceDir( "sound", "KDE-Sys-Warning.ogg");
+ KOPrefs::instance()->audioFilePathItem()->setValue( defAudioFile + "KDE-Sys-Warning.ogg" );
+ }
+ TQString filter = i18n( "*.ogg *.wav *.mp3 *.wma *.flac *.aiff *.raw *.au *.ra|"
+ "Audio Files (*.ogg *.wav *.mp3 *.wma *.flac *.aiff *.raw *.au *.ra)" );
+ KURLRequester *rq = addWidPath( KOPrefs::instance()->audioFilePathItem(),
+ audioFileRemindersBox, filter )->urlRequester();
+ rq->setEnabled( cb->isChecked() );
+ connect( cb, TQT_SIGNAL(toggled(bool)),
+ rq, TQT_SLOT(setEnabled( bool)) );
+
+ TQHBox *eventRemindersBox = new TQHBox( remindersGroupBox );
+ addWidBool( KOPrefs::instance()->defaultEventRemindersItem(), eventRemindersBox )->checkBox();
+
+ TQHBox *todoRemindersBox = new TQHBox( remindersGroupBox );
+ addWidBool( KOPrefs::instance()->defaultTodoRemindersItem(), todoRemindersBox )->checkBox();
TQLabel *alarmDefaultLabel = new TQLabel( i18n( "Enable reminders by default:" ), topFrame);
topLayout->addWidget( alarmDefaultLabel, 6, 0 );
@@ -386,8 +415,9 @@ class KOPrefsDialogTime : public KPrefsModule
setCombo( mTimeZoneCombo,
i18n( KOPrefs::instance()->mTimeZoneId.utf8() ) );
- mAlarmTimeCombo->setCurrentItem( KOPrefs::instance()->mAlarmTime );
- mAlarmTimeDefaultCheckBox->setChecked ( KOPrefs::instance()->mAlarmsEnabledByDefault );
+ mReminderTimeSpin->setValue( KOPrefs::instance()->mReminderTime );
+ mReminderUnitsCombo->setCurrentItem( KOPrefs::instance()->mReminderTimeUnits );
+
for ( int i = 0; i < 7; ++i ) {
mWorkDays[i]->setChecked( (1<<i) & (KOPrefs::instance()->mWorkWeekMask) );
}
@@ -409,8 +439,9 @@ class KOPrefsDialogTime : public KPrefsModule
TQString::null :
mRegionMap[mHolidayCombo->currentText()];
- KOPrefs::instance()->mAlarmTime = mAlarmTimeCombo->currentItem();
- KOPrefs::instance()->mAlarmsEnabledByDefault = mAlarmTimeDefaultCheckBox->isChecked();
+ KOPrefs::instance()->mReminderTime = mReminderTimeSpin->value();
+ KOPrefs::instance()->mReminderTimeUnits = mReminderUnitsCombo->currentItem();
+
int mask = 0;
for ( int i = 0; i < 7; ++i ) {
if (mWorkDays[i]->isChecked()) mask = mask | (1<<i);
@@ -440,7 +471,8 @@ class KOPrefsDialogTime : public KPrefsModule
TQStringList tzonenames;
TQComboBox *mHolidayCombo;
TQMap<TQString,TQString> mRegionMap;
- TQComboBox *mAlarmTimeCombo;
+ KIntSpinBox *mReminderTimeSpin;
+ KComboBox *mReminderUnitsCombo;
TQCheckBox *mAlarmTimeDefaultCheckBox;
TQCheckBox *mWorkDays[7];
};
@@ -483,6 +515,7 @@ class KOPrefsDialogViews : public KPrefsModule
topFrame );
addWidBool( KOPrefs::instance()->dailyRecurItem(), dateNavGroup );
addWidBool( KOPrefs::instance()->weeklyRecurItem(), dateNavGroup );
+ addWidBool( KOPrefs::instance()->weekNumbersShowWorkItem(), dateNavGroup );
topLayout->addWidget( dateNavGroup );
@@ -520,20 +553,14 @@ class KOPrefsDialogViews : public KPrefsModule
topLayout->addWidget( agendaGroup );
- /*** Month and Todo view groups side by side, to save space. ***/
- TQHBoxLayout *hbox = new TQHBoxLayout();
- topLayout->addLayout( hbox );
-
/*** Month View Group ***/
TQGroupBox *monthGroup = new TQGroupBox( 1, Horizontal,
i18n("Month View"),
topFrame );
addWidBool( KOPrefs::instance()->enableMonthScrollItem(), monthGroup );
addWidBool( KOPrefs::instance()->fullViewMonthItem(), monthGroup );
- addWidBool( KOPrefs::instance()->monthViewUsesCategoryColorItem(),
- monthGroup );
- addWidBool( KOPrefs::instance()->monthViewUsesResourceColorItem(), monthGroup );
- hbox->addWidget( monthGroup );
+ addWidCombo( KOPrefs::instance()->monthItemColorsItem(), monthGroup );
+ topLayout->addWidget( monthGroup );
/*** Todo View Group ***/
@@ -542,7 +569,7 @@ class KOPrefsDialogViews : public KPrefsModule
topFrame );
addWidBool( KOPrefs::instance()->fullViewTodoItem(), todoGroup );
addWidBool( KOPrefs::instance()->recordTodosInJournalsItem(), todoGroup );
- hbox->addWidget( todoGroup );
+ topLayout->addWidget( todoGroup );
topLayout->addStretch( 1 );
@@ -642,40 +669,42 @@ KOPrefsDialogColors::KOPrefsDialogColors( TQWidget *parent, const char *name )
topLayout->addWidget(highlightColor->label(),1,0);
topLayout->addWidget(highlightColor->button(),1,1);
- KPrefsWidColor *eventColor =
- addWidColor( KOPrefs::instance()->eventColorItem(), topFrame );
- topLayout->addWidget(eventColor->label(),2,0);
- topLayout->addWidget(eventColor->button(),2,1);
-
// agenda view background color
KPrefsWidColor *agendaBgColor =
addWidColor( KOPrefs::instance()->agendaBgColorItem(), topFrame );
- topLayout->addWidget(agendaBgColor->label(),3,0);
- topLayout->addWidget(agendaBgColor->button(),3,1);
+ topLayout->addWidget(agendaBgColor->label(),2,0);
+ topLayout-&