diff --git a/korganizer/actionmanager.cpp b/korganizer/actionmanager.cpp index 1777cff569..f1c51119ef 100644 --- a/korganizer/actionmanager.cpp +++ b/korganizer/actionmanager.cpp @@ -1,1951 +1,1945 @@ /* This file is part of KOrganizer. Copyright (c) 2002 Mike Pilone Copyright (c) 2002 Don Sanders Copyright (c) 2004 Cornelius Schumacher Copyright (C) 2004 Reinhold Kainhofer Copyright (c) 2005 Rafal Rzepecki Copyright (c) 2010 Laurent Montel Copyright (c) 2012 Allen Winter This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. As a special exception, permission is given to link this program with any edition of Qt, and distribute the resulting executable, without including the source code for Qt in the source distribution. */ #include "actionmanager.h" #include "akonadicollectionview.h" #include "calendaradaptor.h" #include "calendarview.h" #include "htmlexportjob.h" #include "htmlexportsettings.h" #include "kocore.h" #include "kodialogmanager.h" #include "korganizeradaptor.h" #include "koglobals.h" #include "koprefs.h" #include "koviewmanager.h" #include "kowindowlist.h" #include "reminderclient.h" #include "kocheckableproxymodel.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include KOWindowList *ActionManager::mWindowList = 0; ActionManager::ActionManager( KXMLGUIClient *client, CalendarView *widget, QObject *parent, KOrg::MainWindow *mainWindow, bool isPart, KMenuBar *menuBar ) : QObject( parent ), mCollectionViewShowAction( 0 ), mCollectionView( 0 ), mCollectionViewStateSaver( 0 ), mCollectionSelectionModelStateSaver( 0 ) { new KOrgCalendarAdaptor( this ); QDBusConnection::sessionBus().registerObject( QLatin1String("/Calendar"), this ); mGUIClient = client; mACollection = mGUIClient->actionCollection(); mCalendarView = widget; mIsPart = isPart; mTempFile = 0; mHtmlExportSync = false; mMainWindow = mainWindow; mMenuBar = menuBar; } ActionManager::~ActionManager() { // Remove Part plugins KOCore::self()->unloadParts( mMainWindow, mParts ); delete mTempFile; // Take this window out of the window list. mWindowList->removeWindow( mMainWindow ); delete mCollectionSelectionModelStateSaver; delete mCollectionViewStateSaver; delete mCalendarView; } void ActionManager::toggleMenubar( bool dontShowWarning ) { if ( mMenuBar ) { if ( mHideMenuBarAction->isChecked() ) { mMenuBar->show(); } else { if ( !dontShowWarning ) { QString accel = mHideMenuBarAction->shortcut().toString(); KMessageBox::information( mCalendarView, i18n( "This will hide the menu bar completely." " You can show it again by typing %1.", accel ), i18n("Hide menu bar"), QLatin1String("HideMenuBarWarning") ); } mMenuBar->hide(); } KOPrefs::instance()->setShowMenuBar( mHideMenuBarAction->isChecked() ); } } // see the Note: below for why this method is necessary void ActionManager::init() { // add this instance of the window to the static list. if ( !mWindowList ) { mWindowList = new KOWindowList; // Show tip of the day, when the first calendar is shown. if ( !mIsPart ) { QTimer::singleShot( 0, this, SLOT(showTipOnStart()) ); } } // Note: We need this ActionManager to be fully constructed, and // parent() to have a valid reference to it before the following // addWindow is called. mWindowList->addWindow( mMainWindow ); // initialize the KAction instances initActions(); // set up autoExporting stuff mAutoExportTimer = new QTimer( this ); connect( mAutoExportTimer, SIGNAL(timeout()), SLOT(checkAutoExport()) ); if ( KOPrefs::instance()->mAutoExport && KOPrefs::instance()->mAutoExportInterval > 0 ) { mAutoExportTimer->start( 1000 * 60 * KOPrefs::instance()->mAutoExportInterval ); } // set up autoSaving stuff mAutoArchiveTimer = new QTimer( this ); mAutoArchiveTimer->setSingleShot( true ); connect( mAutoArchiveTimer, SIGNAL(timeout()), SLOT(slotAutoArchive()) ); // First auto-archive should be in 5 minutes (like in kmail). if ( CalendarSupport::KCalPrefs::instance()->mAutoArchive ) { mAutoArchiveTimer->start( 5 * 60 * 1000 ); // singleshot } setTitle(); connect( mCalendarView, SIGNAL(modifiedChanged(bool)), SLOT(setTitle()) ); connect( mCalendarView, SIGNAL(configChanged()), SLOT(updateConfig()) ); connect( mCalendarView, SIGNAL(incidenceSelected(Akonadi::Item,QDate)), this, SLOT(processIncidenceSelection(Akonadi::Item,QDate)) ); connect( mCalendarView, SIGNAL(exportHTML(KOrg::HTMLExportSettings*)), this, SLOT(exportHTML(KOrg::HTMLExportSettings*)) ); processIncidenceSelection( Akonadi::Item(), QDate() ); // Update state of paste action mCalendarView->checkClipboard(); } Akonadi::ETMCalendar::Ptr ActionManager::calendar() const { return mCalendarView->calendar(); } void ActionManager::createCalendarAkonadi() { Q_ASSERT( calendar() ); KConfig *config = KOGlobals::self()->config(); mCollectionSelectionModelStateSaver = new KViewStateMaintainer( config->group( "GlobalCollectionSelection" ) ); mCollectionSelectionModelStateSaver->setSelectionModel( calendar()->checkableProxyModel()->selectionModel() ); AkonadiCollectionViewFactory factory( mCalendarView ); mCalendarView->addExtension( &factory ); mCollectionView = factory.collectionView(); mCollectionView->setObjectName( QLatin1String("Resource View") ); connect( mCollectionView, SIGNAL(resourcesAddedRemoved()), SLOT(slotResourcesAddedRemoved())); connect( mCollectionView, SIGNAL(defaultResourceChanged(Akonadi::Collection)), SLOT(slotDefaultResourceChanged(Akonadi::Collection)) ); connect( mCollectionView, SIGNAL(colorsChanged()), mCalendarView, SLOT(updateConfig()) ); mCollectionViewStateSaver = new KViewStateMaintainer( config->group( "GlobalCollectionView" ) ); mCollectionViewStateSaver->setView( mCollectionView->view() ); KCheckableProxyModel *checkableProxy = calendar()->checkableProxyModel(); QItemSelectionModel *selectionModel = checkableProxy->selectionModel(); mCollectionView->setCollectionSelectionProxyModel( checkableProxy ); CalendarSupport::CollectionSelection *collectionSelection = new CalendarSupport::CollectionSelection( selectionModel ); EventViews::EventView::setGlobalCollectionSelection( collectionSelection ); mCalendarView->readSettings(); connect( calendar().data(), SIGNAL(calendarChanged()), mCalendarView, SLOT(resourcesChanged()) ); connect( mCalendarView, SIGNAL(configChanged()), SLOT(updateConfig()) ); calendar()->setOwner( KCalCore::Person::Ptr( new KCalCore::Person( CalendarSupport::KCalPrefs::instance()->fullName(), CalendarSupport::KCalPrefs::instance()->email() ) ) ); } void ActionManager::initActions() { KAction *action; /*************************** FILE MENU **********************************/ //~~~~~~~~~~~~~~~~~~~~~~~ LOADING / SAVING ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if ( mIsPart ) { if ( mMainWindow->hasDocument() ) { KAction *a = mACollection->addAction( KStandardAction::Open, this, SLOT(file_open()) ); mACollection->addAction( QLatin1String("korganizer_open"), a ); } QAction *a = mACollection->addAction( KStandardAction::Print, mCalendarView, SLOT(print()) ); mACollection->addAction( QLatin1String("korganizer_print"), a ); a = mACollection->addAction( KStandardAction::PrintPreview, mCalendarView, SLOT(print()) ); mACollection->addAction( QLatin1String("korganizer_print_preview"), a ); a->setEnabled( !KMimeTypeTrader::self()->query( QLatin1String("application/pdf"), QLatin1String("KParts/ReadOnlyPart") ).isEmpty() ); } else { KStandardAction::open( this, SLOT(file_open()), mACollection ); KStandardAction::print( mCalendarView, SLOT(print()), mACollection ); QAction *preview = KStandardAction::printPreview( mCalendarView, SLOT(printPreview()), mACollection ); preview->setEnabled( !KMimeTypeTrader::self()->query( QLatin1String("application/pdf"), QLatin1String("KParts/ReadOnlyPart")).isEmpty() ); } //~~~~~~~~~~~~~~~~~~~~~~~~ IMPORT / EXPORT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ mImportAction = new KAction( i18n( "Import &Calendar..." ), this ); mImportAction->setHelpText( i18n( "Merge the contents of another iCalendar" ) ); mImportAction->setWhatsThis( i18n( "Select this menu entry if you would like to merge the contents " "of another iCalendar into your current calendar." ) ); mACollection->addAction( QLatin1String("import_icalendar"), mImportAction ); connect( mImportAction, SIGNAL(triggered(bool)), SLOT(file_import()) ); KAction *importAction = new KAction( i18n( "&Import From UNIX Ical Tool" ), this ); importAction->setHelpText( i18n( "Import a calendar in another format" ) ); importAction->setWhatsThis( i18n( "Select this menu entry if you would like to import the contents " "of a non-iCalendar formatted file into your current calendar." ) ); mACollection->addAction( QLatin1String("import_ical"), importAction ); connect( importAction, SIGNAL(triggered(bool)), SLOT(file_icalimport()) ); action = new KAction( i18n( "Get &Hot New Stuff..." ), this ); mACollection->addAction( QLatin1String("downloadnewstuff"), action ); connect( action, SIGNAL(triggered(bool)), SLOT(downloadNewStuff()) ); action = new KAction( i18n( "Export &Web Page..." ), this ); mACollection->addAction( QLatin1String("export_web"), action ); connect( action, SIGNAL(triggered(bool)), mCalendarView, SLOT(exportWeb()) ); action = new KAction( i18n( "Export as &iCalendar..." ), this ); mACollection->addAction( QLatin1String("export_icalendar"), action ); connect( action, SIGNAL(triggered(bool)), mCalendarView, SLOT(exportICalendar()) ); action = new KAction( i18n( "Export as &vCalendar..." ), this ); mACollection->addAction( QLatin1String("export_vcalendar"), action ); connect( action, SIGNAL(triggered(bool)), mCalendarView, SLOT(exportVCalendar()) ); //Laurent: 2009-03-24 comment it until upload will implement //action = new KAction( i18n( "Upload &Hot New Stuff..." ), this ); //mACollection->addAction( "uploadnewstuff", action ); //connect( action, SIGNAL(triggered(bool)), SLOT(uploadNewStuff()) ); action = new KAction( i18n( "Archive O&ld Entries..." ), this ); mACollection->addAction( QLatin1String("file_archive"), action ); connect( action, SIGNAL(triggered(bool)), SLOT(file_archive()) ); action = new KAction( i18n( "Pur&ge Completed To-dos" ), mACollection ); mACollection->addAction( QLatin1String("purge_completed"), action ); connect( action, SIGNAL(triggered(bool)), mCalendarView, SLOT(purgeCompleted()) ); /************************** EDIT MENU *********************************/ QAction *pasteAction; Akonadi::History *history = mCalendarView->history(); if ( mIsPart ) { // edit menu mCutAction = mACollection->addAction( KStandardAction::Cut, QLatin1String("korganizer_cut"), mCalendarView, SLOT(edit_cut()) ); mCopyAction = mACollection->addAction( KStandardAction::Copy, QLatin1String("korganizer_copy"), mCalendarView, SLOT(edit_copy()) ); pasteAction = mACollection->addAction( KStandardAction::Paste, QLatin1String("korganizer_paste"), mCalendarView, SLOT(edit_paste()) ); mUndoAction = mACollection->addAction( KStandardAction::Undo, QLatin1String("korganizer_undo"), history, SLOT(undo()) ); mRedoAction = mACollection->addAction( KStandardAction::Redo, QLatin1String("korganizer_redo"), history, SLOT(redo()) ); } else { mCutAction = KStandardAction::cut( mCalendarView, SLOT(edit_cut()), mACollection ); mCopyAction = KStandardAction::copy( mCalendarView, SLOT(edit_copy()), mACollection ); pasteAction = KStandardAction::paste( mCalendarView, SLOT(edit_paste()), mACollection ); mUndoAction = KStandardAction::undo( history, SLOT(undo()), mACollection ); mRedoAction = KStandardAction::redo( history, SLOT(redo()), mACollection ); } mDeleteAction = new KAction( KIcon( QLatin1String("edit-delete") ), i18n( "&Delete" ), this ); mACollection->addAction( QLatin1String("edit_delete"), mDeleteAction ); connect( mDeleteAction, SIGNAL(triggered(bool)), mCalendarView, SLOT(appointment_delete()) ); if ( mIsPart ) { QAction *a = KStandardAction::find( mCalendarView->dialogManager(), SLOT(showSearchDialog()), mACollection ); mACollection->addAction( QLatin1String("korganizer_find"), a ); } else { KStandardAction::find( mCalendarView->dialogManager(), SLOT(showSearchDialog()), mACollection ); } pasteAction->setEnabled( false ); mUndoAction->setEnabled( false ); mRedoAction->setEnabled( false ); connect( mCalendarView, SIGNAL(pasteEnabled(bool)), pasteAction, SLOT(setEnabled(bool)) ); connect( history, SIGNAL(changed()), SLOT(updateUndoRedoActions()) ); /************************** VIEW MENU *********************************/ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~ VIEWS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ action = new KAction( KIcon( QLatin1String("view-calendar-upcoming-events") ), i18n( "What's &Next" ), this ); mACollection->addAction( QLatin1String("view_whatsnext"), action ); connect( action, SIGNAL(triggered(bool)), mCalendarView->viewManager(), SLOT(showWhatsNextView()) ); action = new KAction( KIcon( QLatin1String("view-calendar-month") ), i18n( "&Month" ), this ); mACollection->addAction( QLatin1String("view_month"), action ); connect( action, SIGNAL(triggered(bool)), mCalendarView->viewManager(), SLOT(showMonthView()) ); - action = new KAction( KIcon( QLatin1String("view-calendar-agenda") ), i18n( "&Agenda" ), this ); - mACollection->addAction( QLatin1String("view_agenda"), action ); - connect( action, SIGNAL(triggered(bool)), - mCalendarView->viewManager(), SLOT(showAgendaView()) ); // action = new KAction( KIcon( QLatin1String("view-calendar-list") ), i18n( "&Event List" ), this ); // mACollection->addAction( QLatin1String("view_list"), action ); // connect( action, SIGNAL(triggered(bool)), mCalendarView->viewManager(), // SLOT(showListView()) ); // action = new KAction( KIcon( QLatin1String("view-calendar-tasks") ), i18n( "&To-do List" ), this ); // mACollection->addAction( QLatin1String("view_todo"), action ); // connect( action, SIGNAL(triggered(bool)), mCalendarView->viewManager(), // SLOT(showTodoView()) ); // action = new KAction( KIcon( QLatin1String("view-calendar-journal" )), i18n( "&Journal" ), this ); // mACollection->addAction( QLatin1String("view_journal"), action ); // connect( action, SIGNAL(triggered(bool)), mCalendarView->viewManager(), // SLOT(showJournalView()) ); // action = new KAction( KIcon( QLatin1String("view-calendar-timeline") ), i18n( "Time&line" ), this ); // mACollection->addAction( QLatin1String("view_timeline"), action ); // connect( action, SIGNAL(triggered(bool)), mCalendarView->viewManager(), // SLOT(showTimeLineView()) ); // action = new KAction( KIcon( QLatin1String("view-calendar-time-spent") ), i18n( "Time&spent" ), this ); // mACollection->addAction( QLatin1String("view_timespent"), action ); // connect( action, SIGNAL(triggered(bool)), mCalendarView->viewManager(), // SLOT(showTimeSpentView()) ); //~~~~~~~~~~~~~~~~~~~~~~~~~~~ REFRESH ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ action = new KAction( i18n( "&Refresh" ), this ); mACollection->addAction( QLatin1String("update"), action ); connect( action, SIGNAL(triggered(bool)), mCalendarView, SLOT(updateView()) ); //~~~~~~~~~~~~~~~~~~~~~~~~~~~ FILTER ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ mFilterAction = new KSelectAction( i18n( "F&ilter" ), this ); mFilterAction->setToolBarMode( KSelectAction::MenuMode ); mACollection->addAction( QLatin1String("filter_select"), mFilterAction ); mFilterAction->setEditable( false ); connect( mFilterAction, SIGNAL(triggered(int)), mCalendarView, SLOT(filterActivated(int)) ); connect( mCalendarView, SIGNAL(filtersUpdated(QStringList,int)), this, SLOT(setItems(QStringList,int)) ); connect( mCalendarView, SIGNAL(filterChanged()), this, SLOT(setTitle()) ); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ZOOM ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // TODO: try to find / create better icons for the following 4 actions action = new KAction( KIcon( QLatin1String("zoom-in") ), i18n( "In Horizontally" ), this ); action->setEnabled( mCalendarView->currentView()->supportsZoom() ); mACollection->addAction( QLatin1String("zoom_in_horizontally"), action ); connect( action, SIGNAL(triggered(bool)), mCalendarView->viewManager(), SLOT(zoomInHorizontally()) ); action = new KAction( KIcon( QLatin1String("zoom-out") ), i18n( "Out Horizontally" ), this ); action->setEnabled( mCalendarView->currentView()->supportsZoom() ); mACollection->addAction( QLatin1String("zoom_out_horizontally"), action ); connect( action, SIGNAL(triggered(bool)), mCalendarView->viewManager(), SLOT(zoomOutHorizontally()) ); action = new KAction( KIcon( QLatin1String("zoom-in") ), i18n( "In Vertically" ), this ); action->setEnabled( mCalendarView->currentView()->supportsZoom() ); mACollection->addAction( QLatin1String("zoom_in_vertically"), action ); connect( action, SIGNAL(triggered(bool)), mCalendarView->viewManager(), SLOT(zoomInVertically()) ); action = new KAction( KIcon( QLatin1String("zoom-out") ), i18n( "Out Vertically" ), this ); action->setEnabled( mCalendarView->currentView()->supportsZoom() ); mACollection->addAction( QLatin1String("zoom_out_vertically"), action ); connect( action, SIGNAL(triggered(bool)), mCalendarView->viewManager(), SLOT(zoomOutVertically()) ); /************************** Actions MENU *********************************/ bool isRTL = QApplication::isRightToLeft(); action = new KAction( KIcon( QLatin1String("go-jump-today") ), i18nc( "@action Jump to today", "To &Today" ), this ); action->setIconText( i18n( "Today" ) ); action->setHelpText( i18n( "Scroll to Today" ) ); mACollection->addAction( QLatin1String("go_today"), action ); connect( action, SIGNAL(triggered(bool)), mCalendarView, SLOT(goToday()) ); action = new KAction( KIcon( isRTL ? QLatin1String("go-next") : QLatin1String("go-previous") ), i18nc( "scroll backward", "&Backward" ), this ); action->setIconText( i18nc( "scroll backward", "Back" ) ); action->setHelpText( i18n( "Scroll Backward" ) ); mACollection->addAction( QLatin1String("go_previous"), action ); connect( action, SIGNAL(triggered(bool)), mCalendarView, SLOT(goPrevious()) ); // Changing the action text by setText makes the toolbar button disappear. // This has to be fixed first, before the connects below can be reenabled. /* connect( mCalendarView, SIGNAL(changeNavStringPrev(QString)), action, SLOT(setText(QString)) ); connect( mCalendarView, SIGNAL(changeNavStringPrev(QString)), this, SLOT(dumpText(QString)) );*/ action = new KAction( KIcon( isRTL ? QLatin1String("go-previous") : QLatin1String("go-next") ), i18nc( "scroll forward", "&Forward" ), this ); action->setIconText( i18nc( "scoll forward", "Forward" ) ); action->setHelpText( i18n( "Scroll Forward" ) ); mACollection->addAction( QLatin1String("go_next"), action ); connect( action, SIGNAL(triggered(bool)), mCalendarView, SLOT(goNext()) ); /* connect( mCalendarView,SIGNAL(changeNavStringNext(QString)), action,SLOT(setText(QString)) ); */ action = new KAction( KIcon( QLatin1String("view-calendar-day") ), i18n( "&Day" ), this ); mACollection->addAction( QLatin1String("select_day"), action ); - action->setEnabled( mCalendarView->currentView()->supportsDateRangeSelection() ); connect( action, SIGNAL(triggered(bool)), mCalendarView->viewManager(), SLOT(selectDay()) ); mNextXDays = new KAction( KIcon( QLatin1String("view-calendar-upcoming-days") ), QString(), this ); mNextXDays->setEnabled( mCalendarView->currentView()->supportsDateRangeSelection() ); mACollection->addAction( QLatin1String("select_nextx"), mNextXDays ); connect( mNextXDays, SIGNAL(triggered(bool)), mCalendarView->viewManager(), SLOT(selectNextX()) ); mNextXDays->setText( i18np( "&Next Day", "&Next %1 Days", KOPrefs::instance()->mNextXDays ) ); action = new KAction( KIcon( QLatin1String("view-calendar-workweek") ), i18n( "W&ork Week" ), this ); action->setEnabled( mCalendarView->currentView()->supportsDateRangeSelection() ); mACollection->addAction( QLatin1String("select_workweek"), action ); connect( action, SIGNAL(triggered(bool)), mCalendarView->viewManager(), SLOT(selectWorkWeek()) ); action = new KAction( KIcon( QLatin1String("view-calendar-week") ), i18n( "&Week" ), this ); - action->setEnabled( mCalendarView->currentView()->supportsDateRangeSelection() ); mACollection->addAction( QLatin1String("select_week"), action ); connect( action, SIGNAL(triggered(bool)), mCalendarView->viewManager(), SLOT(selectWeek()) ); /************************** Actions MENU *********************************/ mNewEventAction = new KAction( KIcon( QLatin1String("appointment-new") ), i18n( "New E&vent..." ), this ); //mNewEventAction->setIconText( i18nc( "@action:intoolbar create a new event", "Event" ) ); mNewEventAction->setHelpText( i18n( "Create a new Event" ) ); mACollection->addAction( QLatin1String("new_event"), mNewEventAction ); connect( mNewEventAction, SIGNAL(triggered(bool)), this, SLOT(slotNewEvent()) ); mNewJournalAction = new KAction( KIcon( QLatin1String("journal-new") ), i18n( "New &Journal..." ), this ); //mNewJournalAction->setIconText( i18n( "Journal" ) ); mNewJournalAction->setHelpText( i18n( "Create a new Journal" ) ); mACollection->addAction( QLatin1String("new_journal"), mNewJournalAction ); connect( mNewJournalAction, SIGNAL(triggered(bool)), this, SLOT(slotNewJournal()) ); mConfigureViewAction = new KAction( KIcon( QLatin1String("configure") ), i18n( "Configure View..." ), this ); mConfigureViewAction->setIconText( i18n( "Configure" ) ); mConfigureViewAction->setHelpText( i18n( "Configure the view" ) ); mConfigureViewAction->setEnabled( mCalendarView->currentView() && mCalendarView->currentView()->hasConfigurationDialog() ); mACollection->addAction( QLatin1String("configure_view"), mConfigureViewAction ); connect( mConfigureViewAction, SIGNAL(triggered(bool)), mCalendarView, SLOT(configureCurrentView()) ); mShowIncidenceAction = new KAction( i18n( "&Show" ), this ); mACollection->addAction( QLatin1String("show_incidence"), mShowIncidenceAction ); connect( mShowIncidenceAction, SIGNAL(triggered(bool)), mCalendarView, SLOT(showIncidence()) ); mEditIncidenceAction = new KAction( i18n( "&Edit..." ), this ); mACollection->addAction( QLatin1String("edit_incidence"), mEditIncidenceAction ); connect( mEditIncidenceAction, SIGNAL(triggered(bool)), mCalendarView, SLOT(editIncidence()) ); mDeleteIncidenceAction = new KAction( i18n( "&Delete" ), this ); mACollection->addAction( QLatin1String("delete_incidence"), mDeleteIncidenceAction ); connect( mDeleteIncidenceAction, SIGNAL(triggered(bool)), mCalendarView, SLOT(deleteIncidence()) ); mDeleteIncidenceAction->setShortcut( QKeySequence( Qt::Key_Delete ) ); action = new KAction( i18n( "&Make Sub-to-do Independent" ), this ); mACollection->addAction( QLatin1String("unsub_todo"), action ); connect( action, SIGNAL(triggered(bool)), mCalendarView, SLOT(todo_unsub()) ); action->setEnabled( false ); connect( mCalendarView, SIGNAL(subtodoSelected(bool)), action, SLOT(setEnabled(bool)) ); // TODO: Add item to quickly toggle the reminder of a given incidence // mToggleAlarmAction = new KToggleAction( i18n( "&Activate Reminder" ), 0, // mCalendarView, SLOT(toggleAlarm()), // mACollection, "activate_alarm" ); /************************** SCHEDULE MENU ********************************/ mPublishEvent = new KAction( KIcon( QLatin1String("mail-send") ), i18n( "&Publish Item Information..." ), this ); mACollection->addAction( QLatin1String("schedule_publish"), mPublishEvent ); connect( mPublishEvent, SIGNAL(triggered(bool)), mCalendarView, SLOT(schedule_publish()) ); mPublishEvent->setEnabled( false ); mSendInvitation = new KAction( KIcon( QLatin1String("mail-send") ), i18n( "Send &Invitation to Attendees" ), this ); mACollection->addAction( QLatin1String("schedule_request"), mSendInvitation ); connect( mSendInvitation, SIGNAL(triggered(bool)), mCalendarView, SLOT(schedule_request()) ); mSendInvitation->setEnabled( false ); connect( mCalendarView, SIGNAL(organizerEventsSelected(bool)), mSendInvitation, SLOT(setEnabled(bool)) ); mRequestUpdate = new KAction( i18n( "Re&quest Update" ), this ); mACollection->addAction( QLatin1String("schedule_refresh"), mRequestUpdate ); connect( mRequestUpdate, SIGNAL(triggered(bool)), mCalendarView, SLOT(schedule_refresh()) ); mRequestUpdate->setEnabled( false ); connect( mCalendarView, SIGNAL(groupEventsSelected(bool)), mRequestUpdate, SLOT(setEnabled(bool)) ); mSendCancel = new KAction( i18n( "Send &Cancellation to Attendees" ), this ); mACollection->addAction( QLatin1String("schedule_cancel"), mSendCancel ); connect( mSendCancel, SIGNAL(triggered(bool)), mCalendarView, SLOT(schedule_cancel()) ); mSendCancel->setEnabled( false ); connect( mCalendarView, SIGNAL(organizerEventsSelected(bool)), mSendCancel, SLOT(setEnabled(bool)) ); mSendStatusUpdate = new KAction( KIcon(QLatin1String( "mail-reply-sender") ), i18n( "Send Status &Update" ), this ); mACollection->addAction( QLatin1String("schedule_reply"), mSendStatusUpdate ); connect( mSendStatusUpdate, SIGNAL(triggered(bool)), mCalendarView, SLOT(schedule_reply()) ); mSendStatusUpdate->setEnabled( false ); connect( mCalendarView, SIGNAL(groupEventsSelected(bool)), mSendStatusUpdate, SLOT(setEnabled(bool)) ); mRequestChange = new KAction( i18nc( "counter proposal", "Request Chan&ge" ), this ); mACollection->addAction( QLatin1String("schedule_counter"), mRequestChange ); connect( mRequestChange, SIGNAL(triggered(bool)), mCalendarView, SLOT(schedule_counter()) ); mRequestChange->setEnabled( false ); connect( mCalendarView, SIGNAL(groupEventsSelected(bool)), mRequestChange, SLOT(setEnabled(bool)) ); action = new KAction( i18n( "&Mail Free Busy Information..." ), this ); mACollection->addAction( QLatin1String("mail_freebusy"), action ); connect( action, SIGNAL(triggered(bool)), mCalendarView, SLOT(mailFreeBusy()) ); action->setEnabled( true ); mForwardEvent = new KAction( KIcon( QLatin1String("mail-forward") ), i18n( "&Send as iCalendar..." ), this ); mACollection->addAction( QLatin1String("schedule_forward"), mForwardEvent ); connect( mForwardEvent, SIGNAL(triggered(bool)), mCalendarView, SLOT(schedule_forward()) ); mForwardEvent->setEnabled( false ); action = new KAction( i18n( "&Upload Free Busy Information" ), this ); mACollection->addAction( QLatin1String("upload_freebusy"), action ); connect( action, SIGNAL(triggered(bool)), mCalendarView, SLOT(uploadFreeBusy()) ); action->setEnabled( true ); if ( !mIsPart ) { action = new KAction( KIcon( QLatin1String("help-contents") ), i18n( "&Address Book" ), this ); mACollection->addAction( QLatin1String("addressbook"), action ); connect( action, SIGNAL(triggered(bool)), mCalendarView, SLOT(openAddressbook()) ); } /************************** SETTINGS MENU ********************************/ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SIDEBAR ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ mDateNavigatorShowAction = new KToggleAction( i18n( "Show Date Navigator" ), this ); mACollection->addAction( QLatin1String("show_datenavigator"), mDateNavigatorShowAction ); connect( mDateNavigatorShowAction, SIGNAL(triggered(bool)), SLOT(toggleDateNavigator()) ); mTodoViewShowAction = new KToggleAction( i18n( "Show To-do View" ), this ); mACollection->addAction( QLatin1String("show_todoview"), mTodoViewShowAction ); connect( mTodoViewShowAction, SIGNAL(triggered(bool)), SLOT(toggleTodoView()) ); mEventViewerShowAction = new KToggleAction( i18n( "Show Item Viewer" ), this ); mACollection->addAction( QLatin1String("show_eventviewer"), mEventViewerShowAction ); connect( mEventViewerShowAction, SIGNAL(triggered(bool)), SLOT(toggleEventViewer()) ); KConfigGroup config( KOGlobals::self()->config(), "Settings" ); mDateNavigatorShowAction->setChecked( config.readEntry( "DateNavigatorVisible", true ) ); // if we are a kpart, then let's not show the todo in the left pane by // default since there's also a Todo part and we'll assume they'll be // using that as well, so let's not duplicate it (by default) here mTodoViewShowAction->setChecked( config.readEntry( "TodoViewVisible", false ) ); //mIsPart ? false : true ) ); mEventViewerShowAction->setChecked( config.readEntry( "EventViewerVisible", true ) ); toggleDateNavigator(); toggleTodoView(); toggleEventViewer(); if ( !mMainWindow->hasDocument() ) { mCollectionViewShowAction = new KToggleAction( i18n( "Show Calendar Manager" ), this ); mACollection->addAction( QLatin1String("show_resourceview"), mCollectionViewShowAction ); connect( mCollectionViewShowAction, SIGNAL(triggered(bool)), SLOT(toggleResourceView()) ); mCollectionViewShowAction->setChecked( config.readEntry( "ResourceViewVisible", true ) ); toggleResourceView(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SIDEBAR ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ mHideMenuBarAction = KStandardAction::showMenubar( this, SLOT(toggleMenubar()), mACollection ); mHideMenuBarAction->setChecked( KOPrefs::instance()->showMenuBar() ); toggleMenubar( true ); action = new KAction( i18n( "Configure &Date && Time..." ), this ); mACollection->addAction( QLatin1String("conf_datetime"), action ); connect( action, SIGNAL(triggered(bool)), SLOT(configureDateTime()) ); // TODO: Add an item to show the resource management dlg // new KAction( i18n( "Manage &Calendars..." ), 0, // this, SLOT(manageResources()), // mACollection, "conf_resources" ); action = new KAction( KIcon( QLatin1String("view-filter") ), i18n( "Manage View &Filters..." ), this ); mACollection->addAction( QLatin1String("edit_filters"), action ); connect( action, SIGNAL(triggered(bool)), mCalendarView, SLOT(editFilters()) ); action = new KAction( i18n( "Manage C&ategories..." ), this ); mACollection->addAction( QLatin1String("edit_categories"), action ); connect( action, SIGNAL(triggered(bool)), mCalendarView->dialogManager(), SLOT(showCategoryEditDialog()) ); if ( mIsPart ) { action = new KAction( KIcon( QLatin1String("configure") ), i18n( "&Configure KOrganizer..." ), this ); mACollection->addAction( QLatin1String("korganizer_configure"), action ); connect( action, SIGNAL(triggered(bool)), mCalendarView, SLOT(edit_options()) ); mACollection->addAction( KStandardAction::KeyBindings, QLatin1String("korganizer_configure_shortcuts"), this, SLOT(keyBindings()) ); } else { KStandardAction::preferences( mCalendarView, SLOT(edit_options()), mACollection ); KStandardAction::keyBindings( this, SLOT(keyBindings()), mACollection ); } /**************************** HELP MENU **********************************/ QAction *a = mACollection->addAction( KStandardAction::TipofDay, this, SLOT(showTip()) ); mACollection->addAction( QLatin1String("help_tipofday"), a ); } void ActionManager::setItems( const QStringList &lst, int idx ) { mFilterAction->setItems( lst ); mFilterAction->setCurrentItem( idx ); } void ActionManager::slotResourcesAddedRemoved() { restoreCollectionViewSetting(); } void ActionManager::slotDefaultResourceChanged( const Akonadi::Collection &collection ) { mCalendarView->incidenceChanger()->setDefaultCollection( collection ); } void ActionManager::slotNewEvent() { mCalendarView->newEvent(); } void ActionManager::slotNewJournal() { mCalendarView->newJournal( selectedCollection() ); } void ActionManager::slotMergeFinished(bool success, int total) { Q_ASSERT(sender()); sender()->deleteLater(); mImportAction->setEnabled(true); Akonadi::ICalImporter *importer = qobject_cast(sender()); if (success) { mCalendarView->showMessage(i18np("1 incidence was imported successfully.", "%1 incidences were imported successfully.", total), KMessageWidget::Information); } else { mCalendarView->showMessage(i18n("There was an error while merging the calendar: %1", importer->errorMessage()), KMessageWidget::Error); } } void ActionManager::slotNewResourceFinished(bool success) { Q_ASSERT(sender()); sender()->deleteLater(); Akonadi::ICalImporter *importer = qobject_cast(sender()); mImportAction->setEnabled(true); if (success) { mCalendarView->showMessage(i18n("New calendar added successfully"), KMessageWidget::Information); } else { mCalendarView->showMessage(i18n("Could not add a calendar. Error: %1", importer->errorMessage()), KMessageWidget::Error); } } void ActionManager::readSettings() { // read settings from the KConfig, supplying reasonable // defaults where none are to be found mCalendarView->readSettings(); restoreCollectionViewSetting(); } void ActionManager::restoreCollectionViewSetting() { mCollectionSelectionModelStateSaver->restoreState(); mCollectionViewStateSaver->restoreState(); } void ActionManager::writeSettings() { KConfigGroup config = KOGlobals::self()->config()->group( "Settings" ); mCalendarView->writeSettings(); if ( mDateNavigatorShowAction ) { config.writeEntry( "DateNavigatorVisible", mDateNavigatorShowAction->isChecked() ); } if ( mTodoViewShowAction ) { config.writeEntry( "TodoViewVisible", mTodoViewShowAction->isChecked() ); } if ( mCollectionViewShowAction ) { config.writeEntry( "ResourceViewVisible", mCollectionViewShowAction->isChecked() ); } if ( mEventViewerShowAction ) { config.writeEntry( "EventViewerVisible", mEventViewerShowAction->isChecked() ); } mCollectionViewStateSaver->saveState(); mCollectionSelectionModelStateSaver->saveState(); KConfigGroup selectionViewGroup = KOGlobals::self()->config()->group( "GlobalCollectionView" ); KConfigGroup selectionGroup = KOGlobals::self()->config()->group( "GlobalCollectionSelection" ); selectionGroup.sync(); selectionViewGroup.sync(); config.sync(); } /* void ActionManager::file_new() { emit actionNewMainWindow(); } */ void ActionManager::file_open() { const QString defaultPath = KStandardDirs::locateLocal( "data",QLatin1String("korganizer/") ); const KUrl url = KFileDialog::getOpenUrl( defaultPath, QLatin1String("text/calendar"), dialogParent() ); file_open( url ); } void ActionManager::file_open( const KUrl &url ) { if ( url.isEmpty() ) { return; } // is that URL already opened somewhere else? Activate that window KOrg::MainWindow *korg = ActionManager::findInstance( url ); if ( ( 0 != korg )&&( korg != mMainWindow ) ) { #ifdef Q_WS_X11 KWindowSystem::activateWindow( korg->topLevelWidget()->winId() ); #endif return; } kDebug() << url.prettyUrl(); importCalendar( url ); } void ActionManager::file_icalimport() { // FIXME: eventually, we will need a dialog box to select import type, etc. // for now, hard-coded to ical file, $HOME/.calendar. int retVal = -1; QString progPath; KTemporaryFile tmpfn; tmpfn.open(); QString homeDir = QDir::homePath() + QLatin1String( "/.calendar" ); if ( !QFile::exists( homeDir ) ) { KMessageBox::error( dialogParent(), i18n( "You have no ical file in your home directory.\n" "Import cannot proceed.\n" ) ); return; } KProcess proc; proc << QLatin1String("ical2vcal") << tmpfn.fileName(); retVal = proc.execute(); if ( retVal < 0 ) { kDebug() << "Error executing ical2vcal."; return; } kDebug() << "ical2vcal return value:" << retVal; if ( retVal >= 0 && retVal <= 2 ) { // now we need to MERGE what is in the iCal to the current calendar. const bool success = importURL(KUrl(tmpfn.fileName()), /*merge=*/ true); if ( !success ) { mCalendarView->showMessage( i18n( "KOrganizer encountered some unknown fields while " "parsing your .calendar ical file, and had to " "discard them; please check to see that all " "your relevant data was correctly imported." ), KMessageWidget::Warning); } else { // else nothing, the operation is async and the use will se a message widget when the operation finishes, not now. } } else if ( retVal == -1 ) { // XXX this is bogus mCalendarView->showMessage( i18n( "KOrganizer encountered an error parsing your " ".calendar file from ical; import has failed." ), KMessageWidget::Error ); } else if ( retVal == -2 ) { // XXX this is bogus mCalendarView->showMessage( i18n( "KOrganizer does not think that your .calendar " "file is a valid ical calendar; import has failed." ), KMessageWidget::Error ); } } void ActionManager::file_import() { const KUrl url = KFileDialog::getOpenUrl( KStandardDirs::locateLocal( "data",QLatin1String("korganizer/") ), QLatin1String("text/calendar"), dialogParent() ); if ( !url.isEmpty() ) { // isEmpty if user canceled the dialog importCalendar( url ); } } void ActionManager::file_archive() { mCalendarView->archiveCalendar(); } bool ActionManager::importURL(const KUrl &url, bool merge) { Akonadi::ICalImporter *importer = new Akonadi::ICalImporter(); bool jobStarted; if (merge) { connect(importer, SIGNAL(importIntoExistingFinished(bool,int)), SLOT(slotMergeFinished(bool,int))), jobStarted = importer->importIntoExistingResource(url, Akonadi::Collection()); } else { connect(importer, SIGNAL(importIntoNewFinished(bool)), SLOT(slotNewResourceFinished(bool))); jobStarted = importer->importIntoNewResource(url.path()); } if (jobStarted) { mImportAction->setEnabled(false); } else { // empty error message means user canceled. if (!importer->errorMessage().isEmpty()) mCalendarView->showMessage(i18n("An error occurred: %1", importer->errorMessage()), KMessageWidget::Error); } return jobStarted; } bool ActionManager::saveURL() { QString ext; if ( mURL.isLocalFile() ) { ext = mFile.right( 4 ); } else { ext = mURL.fileName().right( 4 ); } if ( ext == QLatin1String( ".vcs" ) ) { int result = KMessageBox::warningContinueCancel( dialogParent(), i18n( "Your calendar will be saved in iCalendar format. Use " "'Export vCalendar' to save in vCalendar format." ), i18n( "Format Conversion" ), KGuiItem( i18n( "Proceed" ) ), KStandardGuiItem::cancel(), QLatin1String( "dontaskFormatConversion" ), KMessageBox::Notify ); if ( result != KMessageBox::Continue ) { return false; } QString filename = mURL.fileName(); filename.replace( filename.length() - 4, 4, QLatin1String(".ics") ); mURL.setFileName( filename ); if ( mURL.isLocalFile() ) { mFile = mURL.toLocalFile(); } setTitle(); } if ( !mCalendarView->saveCalendar( mFile ) ) { kDebug() << "calendar view save failed."; return false; } if ( !mURL.isLocalFile() ) { if ( !KIO::NetAccess::upload( mFile, mURL, view() ) ) { QString msg = i18n( "Cannot upload calendar to '%1'", mURL.prettyUrl() ); KMessageBox::error( dialogParent(), msg ); return false; } } mMainWindow->showStatusMessage( i18n( "Saved calendar '%1'.", mURL.prettyUrl() ) ); return true; } void ActionManager::exportHTML() { HTMLExportSettings *settings = new HTMLExportSettings( QLatin1String("KOrganizer") ); mSettingsToFree.insert( settings ); // Manually read in the config, because parametrized kconfigxt objects don't // seem to load the config theirselves settings->readConfig(); const QDate qd1 = QDate::currentDate(); QDate qd2 = qd1; if ( settings->monthView() ) { qd2 = qd2.addMonths( 1 ); } else { qd2 = qd2.addDays( 7 ); } settings->setDateStart( QDateTime( qd1 ) ); settings->setDateEnd( QDateTime( qd2 ) ); exportHTML( settings, true/*autoMode*/ ); } void ActionManager::exportHTML( KOrg::HTMLExportSettings *settings, bool autoMode ) { if ( !settings ) { kWarning() << "Settings is null" << settings; return; } if ( settings->outputFile().isEmpty() ) { int result = KMessageBox::questionYesNo( dialogParent(), i18n( "The HTML calendar export file has not been specified yet.\n" "Do you want to set it now?\n\n" "If you answer \"no\" then this export operation will be canceled" ), QString() ); if ( result == KMessageBox::No ) { mMainWindow->showStatusMessage( i18nc( "@info:status", "Calendar HTML operation canceled due to unspecified output file name" ) ); return; } const QString fileName = KFileDialog::getSaveFileName( KGlobalSettings::documentPath(), i18n( "*.html|HTML Files" ), dialogParent(), i18n( "Select path for HTML calendar export" ) ); settings->setOutputFile( fileName ); settings->writeConfig(); } if ( !autoMode && QFileInfo( settings->outputFile() ).exists() ) { if ( KMessageBox::warningContinueCancel( dialogParent(), i18n( "Do you want to overwrite file \"%1\"?", settings->outputFile() ), QString(), KStandardGuiItem::overwrite() ) == KMessageBox::Cancel ) { mMainWindow->showStatusMessage( i18nc( "@info:status", "Calendar HTML operation canceled due to output file overwrite" ) ); return; } } settings->setEMail( CalendarSupport::KCalPrefs::instance()->email() ); settings->setName( CalendarSupport::KCalPrefs::instance()->fullName() ); settings->setCreditName( QLatin1String("KOrganizer") ); settings->setCreditURL( QLatin1String("http://korganizer.kde.org") ); KOrg::HtmlExportJob *exportJob = new KOrg::HtmlExportJob( calendar(), settings, autoMode, mMainWindow, view() ); if ( KOGlobals::self()->holidays() ) { KHolidays::Holiday::List holidays = KOGlobals::self()->holidays()->holidays( settings->dateStart().date(), settings->dateEnd().date() ); foreach ( const KHolidays::Holiday &holiday, holidays ) { exportJob->addHoliday( holiday.date(), holiday.text() ); } } connect( exportJob, SIGNAL(result(KJob*)), SLOT(handleExportJobResult(KJob*)) ); exportJob->start(); } bool ActionManager::saveAsURL( const KUrl &url ) { kDebug() << url.prettyUrl(); if ( url.isEmpty() ) { kDebug() << "Empty URL."; return false; } if ( !url.isValid() ) { kDebug() << "Malformed URL."; return false; } QString fileOrig = mFile; KUrl URLOrig = mURL; KTemporaryFile *tempFile = 0; if ( url.isLocalFile() ) { mFile = url.toLocalFile(); } else { tempFile = new KTemporaryFile; tempFile->setAutoRemove(false); tempFile->open(); mFile = tempFile->fileName(); } mURL = url; bool success = saveURL(); // Save local file and upload local file if ( success ) { delete mTempFile; mTempFile = tempFile; KIO::NetAccess::removeTempFile( fileOrig ); setTitle(); } else { KMessageBox::sorry( dialogParent(), i18n( "Unable to save calendar to the file %1.", mFile ), i18n( "Error" ) ); kDebug() << "failed"; mURL = URLOrig; mFile = fileOrig; delete tempFile; } return success; } #ifdef AKONADI_PORT_DISABLED // can go away, kept for reference bool ActionManager::saveModifiedURL() { kDebug(); // If calendar isn't modified do nothing. if ( !mCalendarView->isModified() ) { return true; } mHtmlExportSync = true; if ( KOPrefs::instance()->mAutoSave && !mURL.isEmpty() ) { // Save automatically, when auto save is enabled. return saveURL(); } else { int result = KMessageBox::warningYesNoCancel( dialogParent(), i18n( "The calendar has been modified.\nDo you want to save it?" ), QString(), KStandardGuiItem::save(), KStandardGuiItem::discard() ); switch( result ) { case KMessageBox::Yes: if ( mURL.isEmpty() ) { KUrl url = getSaveURL(); return saveAsURL( url ); } else { return saveURL(); } case KMessageBox::No: return true; case KMessageBox::Cancel: default: { mHtmlExportSync = false; return false; } } } } #endif KUrl ActionManager::getSaveURL() { KUrl url = KFileDialog::getSaveUrl( KStandardDirs::locateLocal( "data",QLatin1String("korganizer/") ), i18n( "*.ics *.vcs|Calendar Files" ), dialogParent() ); if ( url == KUrl() ) { return url; } QString filename = url.fileName(); QString e = filename.right( 4 ); if ( e != QLatin1String( ".vcs" ) && e != QLatin1String( ".ics" ) ) { // Default save format is iCalendar filename += QLatin1String(".ics"); } url.setFileName( filename ); kDebug() << "url:" << url.url(); return url; } void ActionManager::saveProperties( KConfigGroup &config ) { kDebug(); config.writeEntry( "UseResourceCalendar", !mMainWindow->hasDocument() ); if ( mMainWindow->hasDocument() ) { config.writePathEntry( "Calendar", mURL.url() ); } } void ActionManager::readProperties( const KConfigGroup & ) { mMainWindow->init( false ); } // Configuration changed as a result of the options dialog. void ActionManager::updateConfig() { kDebug(); mNextXDays->setText( i18np( "&Next Day", "&Next %1 Days", KOPrefs::instance()->mNextXDays ) ); KOCore::self()->reloadPlugins(); /* Hide/Show the Reminder Daemon */ if ( !KOPrefs::instance()->mShowReminderDaemon ) { KPIM::ReminderClient::hideDaemon(); } else { KPIM::ReminderClient::showDaemon(); } // Commented out because it crashes KOrganizer. // mParts = KOCore::self()->reloadParts( mMainWindow, mParts ); #ifdef AKONADI_PORT_DISABLED // shouldn't be required anymore if ( mCollectionView ) { mCollectionView->updateView(); } #endif } void ActionManager::configureDateTime() { KProcess proc; proc << QLatin1String("kcmshell4") << QLatin1String("language"); if ( !proc.startDetached() ) { KMessageBox::sorry( dialogParent(), i18n( "Could not start control module for date and time format." ) ); } } void ActionManager::showTip() { KTipDialog::showTip( dialogParent(), QString(), true ); } void ActionManager::showTipOnStart() { KConfigGroup config( KGlobal::config(), "TipOfDay" ); KTipDialog::setShowOnStart( config.readEntry( "RunOnStart", false ) ); KTipDialog::showTip( dialogParent() ); } KOrg::MainWindow *ActionManager::findInstance( const KUrl &url ) { if ( mWindowList ) { if ( url.isEmpty() ) { return mWindowList->defaultInstance(); } else { return mWindowList->findInstance( url ); } } else { return 0; } } bool ActionManager::openURL(const QString &url) { importCalendar(KUrl(url)); return true; } void ActionManager::dumpText( const QString &str ) { kDebug() << str; } void ActionManager::toggleDateNavigator() { bool visible = mDateNavigatorShowAction->isChecked(); if ( mCalendarView ) { mCalendarView->showDateNavigator( visible ); } } void ActionManager::toggleTodoView() { bool visible = mTodoViewShowAction->isChecked(); if ( mCalendarView ) { mCalendarView->showTodoView( visible ); } } void ActionManager::toggleEventViewer() { bool visible = mEventViewerShowAction->isChecked(); if ( mCalendarView ) { mCalendarView->showEventViewer( visible ); } } void ActionManager::toggleResourceView() { const bool visible = mCollectionViewShowAction->isChecked(); if ( mCollectionView ) { if ( visible ) { mCollectionView->show(); } else { mCollectionView->hide(); } } } bool ActionManager::mergeURL( const QString &url ) { return importURL( KUrl( url ), true ); } bool ActionManager::saveAsURL( const QString &url ) { return saveAsURL( KUrl( url ) ); } QString ActionManager::getCurrentURLasString() const { return mURL.url(); } bool ActionManager::editIncidence( Akonadi::Item::Id id ) { return mCalendarView->editIncidence( id ); } bool ActionManager::showIncidence( Akonadi::Item::Id id ) { return mCalendarView->showIncidence( id ); } bool ActionManager::showIncidenceContext( Akonadi::Item::Id id ) { return mCalendarView->showIncidenceContext( id ); } bool ActionManager::handleCommandLine() { KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); KOrg::MainWindow *mainWindow = ActionManager::findInstance( KUrl() ); bool ret = true; if ( !mainWindow ) { kError() << "Unable to find default calendar resources view."; ret = false; } else if ( args->count() <= 0 ) { // No filenames given => all other args are meaningless, show main Window mainWindow->topLevelWidget()->show(); } else { // 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 ) { importURL( args->url( i ), /*merge=*/false ); } } else if ( args->isSet( "merge" ) ) { for ( int i = 0; i < args->count(); ++i ) { importURL( args->url( i ), /*merge=*/true ); } } else { for ( int i = 0; i < args->count(); ++i ) { mainWindow->actionManager()->importCalendar( args->url( i ) ); } } } return ret; } bool ActionManager::deleteIncidence( Akonadi::Item::Id id, bool force ) { return mCalendarView->deleteIncidence( id, force ); } bool ActionManager::addIncidence( const QString &ical ) { return mCalendarView->addIncidence( ical ); } void ActionManager::downloadNewStuff() { kDebug(); KNS3::DownloadDialog dialog(mCalendarView); dialog.exec(); foreach ( const KNS3::Entry &e, dialog.installedEntries() ) { kDebug() << " downloadNewStuff :"; const QStringList lstFile = e.installedFiles(); if ( lstFile.count() != 1 ) { continue; } const QString file = lstFile.at( 0 ); const KUrl filename( file ); kDebug() << "filename :" << filename; if( ! filename.isValid() ) { continue; } KCalCore::FileStorage storage( calendar() ); storage.setFileName( file ); storage.setSaveFormat( new KCalCore::ICalFormat ); if ( !storage.load() ) { KMessageBox::error( mCalendarView, i18n( "Could not load calendar %1.", file ) ); } else { QStringList eventSummaries; KCalCore::Event::List events = calendar()->events(); foreach ( KCalCore::Event::Ptr event, events ) { eventSummaries.append( event->summary() ); } const int result = KMessageBox::warningContinueCancelList( mCalendarView, i18n( "The downloaded events will be merged into your current calendar." ), eventSummaries ); if ( result != KMessageBox::Continue ) { // FIXME (KNS2): hm, no way out here :-) } if ( importURL( KUrl(file), true ) ) { // FIXME (KNS2): here neither } } } } QString ActionManager::localFileName() { return mFile; } class ActionManager::ActionStringsVisitor : public KCalCore::Visitor { public: ActionStringsVisitor() : mShow( 0 ), mEdit( 0 ), mDelete( 0 ) {} bool act( KCalCore::IncidenceBase::Ptr incidence, QAction *show, QAction *edit, QAction *del ) { mShow = show; mEdit = edit; mDelete = del; return incidence->accept( *this, incidence ); } protected: bool visit( KCalCore::Event::Ptr ) { if ( mShow ) { mShow->setText( i18n( "&Show Event" ) ); } if ( mEdit ) { mEdit->setText( i18n( "&Edit Event..." ) ); } if ( mDelete ) { mDelete->setText( i18n( "&Delete Event" ) ); } return true; } bool visit( KCalCore::Todo::Ptr ) { if ( mShow ) { mShow->setText( i18n( "&Show To-do" ) ); } if ( mEdit ) { mEdit->setText( i18n( "&Edit To-do..." ) ); } if ( mDelete ) { mDelete->setText( i18n( "&Delete To-do" ) ); } return true; } bool visit( KCalCore::Journal::Ptr ) { return assignDefaultStrings(); } bool visit( KCalCore::FreeBusy::Ptr ) // to inhibit hidden virtual compile warning { return false; } protected: bool assignDefaultStrings() { if ( mShow ) { mShow->setText( i18n( "&Show" ) ); } if ( mEdit ) { mEdit->setText( i18n( "&Edit..." ) ); } if ( mDelete ) { mDelete->setText( i18n( "&Delete" ) ); } return true; } QAction *mShow; QAction *mEdit; QAction *mDelete; }; void ActionManager::processIncidenceSelection( const Akonadi::Item &item, const QDate &date ) { //kDebug(5850) << "ActionManager::processIncidenceSelection()"; Q_UNUSED( date ); const KCalCore::Incidence::Ptr incidence = CalendarSupport::incidence( item ); if ( !incidence ) { enableIncidenceActions( false ); return; } enableIncidenceActions( true ); if ( !mCalendarView->calendar()->hasRight( item, Akonadi::Collection::CanDeleteItem ) ) { mCutAction->setEnabled( false ); mDeleteAction->setEnabled( false ); } ActionStringsVisitor v; if ( !v.act( incidence, mShowIncidenceAction, mEditIncidenceAction, mDeleteIncidenceAction ) ) { mShowIncidenceAction->setText( i18n( "&Show" ) ); mEditIncidenceAction->setText( i18n( "&Edit..." ) ); mDeleteIncidenceAction->setText( i18n( "&Delete" ) ); } } void ActionManager::enableIncidenceActions( bool enabled ) { mShowIncidenceAction->setEnabled( enabled ); mEditIncidenceAction->setEnabled( enabled ); mDeleteIncidenceAction->setEnabled( enabled ); mCutAction->setEnabled( enabled ); mCopyAction->setEnabled( 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 ); } Akonadi::Collection ActionManager::selectedCollection() const { const QModelIndex index = mCollectionView->view()->currentIndex(); if ( !index.isValid() ) { return Akonadi::Collection(); } return index.data( Akonadi::EntityTreeModel::CollectionRole ).value(); } void ActionManager::keyBindings() { KShortcutsDialog dlg( KShortcutsEditor::AllActions, KShortcutsEditor::LetterShortcutsDisallowed, view() ); if ( mMainWindow ) { dlg.addCollection( mMainWindow->getActionCollection() ); } foreach ( KOrg::Part *part, mParts ) { if ( part ) { dlg.addCollection( part->actionCollection(), part->shortInfo() ); } } dlg.configure(); } void ActionManager::loadParts() { mParts = KOCore::self()->loadParts( mMainWindow ); } void ActionManager::setTitle() { mMainWindow->setTitle(); } void ActionManager::openEventEditor( const QString &text ) { mCalendarView->newEvent( text ); } void ActionManager::openEventEditor( const QString &summary, const QString &description, const QStringList &attachments ) { mCalendarView->newEvent( summary, description, attachments ); } void ActionManager::openEventEditor( const QString &summary, const QString &description, const QStringList &attachments, const QStringList &attendees ) { mCalendarView->newEvent( summary, description, attachments, attendees ); } void ActionManager::openEventEditor( const QString &summary, const QString &description, const QString &uri, const QString &file, const QStringList &attendees, const QString &attachmentMimetype ) { int action = IncidenceEditorNG::GlobalSettings::self()->defaultEmailAttachMethod(); if ( attachmentMimetype != QLatin1String("message/rfc822") ) { action = IncidenceEditorNG::GlobalSettings::Link; } else if ( IncidenceEditorNG::GlobalSettings::self()->defaultEmailAttachMethod() == IncidenceEditorNG::GlobalSettings::Ask ) { KMenu *menu = new KMenu( 0 ); QAction *attachLink = menu->addAction( i18n( "Attach as &link" ) ); QAction *attachInline = menu->addAction( i18n( "Attach &inline" ) ); QAction *attachBody = menu->addAction( i18n( "Attach inline &without attachments" ) ); menu->addSeparator(); menu->addAction( KIcon( QLatin1String("dialog-cancel") ), i18n( "C&ancel" ) ); QAction *ret = menu->exec( QCursor::pos() ); delete menu; if ( ret == attachLink ) { action = IncidenceEditorNG::GlobalSettings::Link; } else if ( ret == attachInline ) { action = IncidenceEditorNG::GlobalSettings::InlineFull; } else if ( ret == attachBody ) { action = IncidenceEditorNG::GlobalSettings::InlineBody; } else { return; } } QString attData; KTemporaryFile tf; tf.setAutoRemove( true ); switch ( action ) { case IncidenceEditorNG::GlobalSettings::Link: attData = uri; break; case IncidenceEditorNG::GlobalSettings::InlineFull: attData = file; break; case IncidenceEditorNG::GlobalSettings::InlineBody: { QFile f( file ); if ( !f.open( QFile::ReadOnly ) ) { return; } KMime::Message *msg = new KMime::Message(); msg->setContent( f.readAll() ); msg->parse(); if ( msg == msg->textContent() || msg->textContent() == 0 ) { // no attachments attData = file; } else { if ( KMessageBox::warningContinueCancel( 0, i18n( "Removing attachments from an email might invalidate its signature." ), i18n( "Remove Attachments" ), KStandardGuiItem::cont(), KStandardGuiItem::cancel(), QLatin1String("BodyOnlyInlineAttachment") ) != KMessageBox::Continue ) { delete msg; return; } KMime::Message *newMsg = new KMime::Message(); newMsg->setHead( msg->head() ); newMsg->setBody( msg->textContent()->body() ); newMsg->parse(); newMsg->contentTransferEncoding()->from7BitString( msg->textContent()->contentTransferEncoding()->as7BitString() ); newMsg->contentType()->from7BitString( msg->textContent()->contentType()->as7BitString() ); newMsg->assemble(); tf.write( newMsg->encodedContent() ); attData = tf.fileName(); } tf.close(); delete msg; break; } default: return; } mCalendarView->newEvent( summary, description, QStringList(attData), attendees, QStringList(attachmentMimetype), action != IncidenceEditorNG::GlobalSettings::Link ); } void ActionManager::openTodoEditor( const QString &text ) { mCalendarView->newTodo( text ); } void ActionManager::openTodoEditor( const QString &summary, const QString &description, const QStringList &attachments ) { mCalendarView->newTodo( summary, description, attachments ); } void ActionManager::openTodoEditor( const QString &summary, const QString &description, const QStringList &attachments, const QStringList &attendees ) { mCalendarView->newTodo( summary, description, attachments, attendees ); } void ActionManager::openTodoEditor( const QString &summary, const QString &description, const QString &uri, const QString &file, const QStringList &attendees, const QString &attachmentMimetype ) { int action = KOPrefs::instance()->defaultTodoAttachMethod(); if ( attachmentMimetype != QLatin1String("message/rfc822") ) { action = KOPrefs::TodoAttachLink; } else if ( KOPrefs::instance()->defaultTodoAttachMethod() == KOPrefs::TodoAttachAsk ) { KMenu *menu = new KMenu( 0 ); QAction *attachLink = menu->addAction( i18n( "Attach as &link" ) ); QAction *attachInline = menu->addAction( i18n( "Attach &inline" ) ); menu->addSeparator(); menu->addAction( KIcon( QLatin1String("dialog-cancel") ), i18n( "C&ancel" ) ); QAction *ret = menu->exec( QCursor::pos() ); delete menu; if ( ret == attachLink ) { action = KOPrefs::TodoAttachLink; } else if ( ret == attachInline ) { action = KOPrefs::TodoAttachInlineFull; } else { return; } } QString attData; switch ( action ) { case KOPrefs::TodoAttachLink: attData = uri; break; case KOPrefs::TodoAttachInlineFull: attData = file; break; default: return; } mCalendarView->newTodo( summary, description, QStringList( attData ), attendees, QStringList( attachmentMimetype ), action != KOPrefs::TodoAttachLink ); } void ActionManager::openJournalEditor( const QDate &date ) { mCalendarView->newJournal( date ); } void ActionManager::openJournalEditor( const QString &text, const QDate &date ) { mCalendarView->newJournal( text, date ); } void ActionManager::openJournalEditor( const QString &text ) { mCalendarView->newJournal( text ); } void ActionManager::showJournalView() { mCalendarView->viewManager()->showJournalView(); } void ActionManager::showTodoView() { mCalendarView->viewManager()->showTodoView(); } void ActionManager::showEventView() { mCalendarView->viewManager()->showEventView(); } void ActionManager::goDate( const QDate &date ) { mCalendarView->goDate( date ); } void ActionManager::goDate( const QString &date ) { goDate( KGlobal::locale()->readDate( date ) ); } void ActionManager::showDate( const QDate &date ) { mCalendarView->showDate( date ); } void ActionManager::updateUndoRedoActions() { Akonadi::History *history = mCalendarView->incidenceChanger()->history(); if ( history->undoAvailable() ) { mUndoAction->setEnabled( true ); mUndoAction->setText( i18n( "Undo: %1", history->nextUndoDescription() ) ); } else { mUndoAction->setEnabled( false ); mUndoAction->setText( i18n( "Undo" ) ); } if ( history->redoAvailable() ) { mRedoAction->setEnabled( true ); mRedoAction->setText( i18n( "Redo: %1", history->nextRedoDescription() ) ); } else { mRedoAction->setEnabled( false ); mRedoAction->setText( i18n( "Redo" ) ); } mUndoAction->setIconText( i18n( "Undo" ) ); } bool ActionManager::queryClose() { return true; } void ActionManager::importCalendar( const KUrl &url ) { if ( !url.isValid() ) { KMessageBox::error( dialogParent(), i18n( "URL '%1' is invalid.", url.prettyUrl() ) ); return; } const QString questionText = i18nc( "@info", "

Would you like to merge this calendar item into an existing calendar " "or use it to create a brand new calendar?

" "

If you select merge, then you will be given the opportunity to select " "the destination calendar.

" "

If you select add, then a new calendar will be created for you automatically.

" ); const int answer = KMessageBox::questionYesNoCancel( dialogParent(), questionText, i18nc( "@title:window", "Import Calendar" ), KGuiItem( i18n( "Merge into existing calendar" ) ), KGuiItem( i18n( "Add as new calendar" ) ) ); switch( answer ) { case KMessageBox::Yes: //merge importURL( url, true ); break; case KMessageBox::No: //import importURL( url, false ); break; default: return; } } void ActionManager::slotAutoArchivingSettingsModified() { if ( CalendarSupport::KCalPrefs::instance()->mAutoArchive ) { mAutoArchiveTimer->start( 4 * 60 * 60 * 1000 ); // check again in 4 hours } else { mAutoArchiveTimer->stop(); } } void ActionManager::slotAutoArchive() { if ( !mCalendarView->calendar() ) { // can this happen? return; } mAutoArchiveTimer->stop(); CalendarSupport::EventArchiver archiver; archiver.runAuto( calendar(), mCalendarView->incidenceChanger(), mCalendarView, false /*no gui*/); // restart timer with the correct delay ( especially useful for the first time ) slotAutoArchivingSettingsModified(); } QWidget *ActionManager::dialogParent() { return mCalendarView->topLevelWidget(); } void ActionManager::checkAutoExport() { // Don't save if auto save interval is zero if ( KOPrefs::instance()->mAutoExportInterval == 0 ) { return; } // has this calendar been saved before? If yes automatically save it. if ( KOPrefs::instance()->mAutoExport ) { exportHTML(); } } void ActionManager::openTodoEditor( const QString &summary, const QString &description, const QStringList &attachmentUris, const QStringList &attendees, const QStringList &attachmentMimetypes, bool attachmentIsInline ) { Q_UNUSED( summary ); Q_UNUSED( description ); Q_UNUSED( attachmentUris ); Q_UNUSED( attendees ); Q_UNUSED( attachmentMimetypes ); Q_UNUSED( attachmentIsInline ); kWarning() << "Not implemented in korg-desktop"; } void ActionManager::openEventEditor( const QString &summary, const QString &description, const QStringList &attachmentUris, const QStringList &attendees, const QStringList &attachmentMimetypes, bool attachmentIsInline ) { Q_UNUSED( summary ); Q_UNUSED( description ); Q_UNUSED( attachmentUris ); Q_UNUSED( attendees ); Q_UNUSED( attachmentMimetypes ); Q_UNUSED( attachmentIsInline ); kWarning() << "Not implemented in korg-desktop"; } void ActionManager::handleExportJobResult( KJob *job ) { HtmlExportJob *htmlExportJob = qobject_cast( job ); Q_ASSERT( htmlExportJob ); if ( mSettingsToFree.contains( htmlExportJob->settings() ) ) { mSettingsToFree.remove( htmlExportJob->settings() ); delete htmlExportJob->settings(); } } diff --git a/korganizer/korganizerui.rc b/korganizer/korganizerui.rc index 5772d4e3fb..216ba804e9 100644 --- a/korganizer/korganizerui.rc +++ b/korganizer/korganizerui.rc @@ -1,192 +1,190 @@ &File &Import &Export &Edit &View - &Zoom &Go &Actions S&chedule &Settings &Sidebar &Help Main Views - Disable Calendar Enable Calendar Calendar Colors diff --git a/korganizer/koviewmanager.cpp b/korganizer/koviewmanager.cpp index ea574e6460..e108241526 100644 --- a/korganizer/koviewmanager.cpp +++ b/korganizer/koviewmanager.cpp @@ -1,700 +1,700 @@ /* This file is part of KOrganizer. Copyright (c) 2001,2003 Cornelius Schumacher Copyright (C) 2003-2004 Reinhold Kainhofer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. As a special exception, permission is given to link this program with any edition of Qt, and distribute the resulting executable, without including the source code for Qt in the source distribution. */ #include "koviewmanager.h" #include "actionmanager.h" #include "calendarview.h" #include "datenavigator.h" #include "koglobals.h" #include "koprefs.h" #include "navigatorbar.h" #include "korganizer/mainwindow.h" #include "views/agendaview/koagendaview.h" #include "views/journalview/kojournalview.h" #include "views/listview/kolistview.h" #include "views/monthview/monthview.h" #include "views/multiagendaview/multiagendaview.h" #include "views/timelineview/kotimelineview.h" #include "views/timespentview/kotimespentview.h" #include "views/todoview/kotodoview.h" #include "views/whatsnextview/kowhatsnextview.h" #include #include #include #include #include KOViewManager::KOViewManager( CalendarView *mainView ) : QObject(), mMainView( mainView ) { mCurrentView = 0; mLastEventView = 0; mWhatsNextView = 0; mTodoView = 0; mAgendaView = 0; mAgendaSideBySideView = 0; mListView = 0; mJournalView = 0; mTimelineView = 0; mAgendaViewTabs = 0; mAgendaViewTabIndex = 0; mTimeSpentView = 0; mMonthView = 0; mRangeMode = NO_RANGE; } KOViewManager::~KOViewManager() { } KOrg::BaseView *KOViewManager::currentView() { return mCurrentView; } void KOViewManager::readSettings( KConfig *config ) { KConfigGroup generalConfig( config, "General" ); const QString view = generalConfig.readEntry( "Current View" ); if ( view == QLatin1String( "WhatsNext" ) ) { showWhatsNextView(); } else if ( view == QLatin1String( "OldMonth" ) ) { // the oldmonth view is gone, so we assume the new month view showMonthView(); } else if ( view == QLatin1String( "List" ) ) { showListView(); mListView->readSettings( config ); } else if ( view == QLatin1String( "Journal" ) ) { showJournalView(); } else if ( view == QLatin1String( "Todo" ) ) { showTodoView(); } else if ( view == QLatin1String( "Timeline" ) ) { showTimeLineView(); } else if ( view == QLatin1String( "TimeSpent" ) ) { showTimeSpentView(); } else if ( view == QLatin1String( "Month" ) ) { showMonthView(); } else { showAgendaView(); } mRangeMode = RangeMode( generalConfig.readEntry( "Range Mode", int( OTHER_RANGE ) ) ); switch ( mRangeMode ) { case WORK_WEEK_RANGE: selectWorkWeek(); break; case WEEK_RANGE: selectWeek(); break; case NEXTX_RANGE: selectNextX(); break; case DAY_RANGE: selectDay(); break; case NO_RANGE: default: // Someone has been playing with the config file. mRangeMode = OTHER_RANGE; } } void KOViewManager::writeSettings( KConfig *config ) { KConfigGroup generalConfig( config, "General" ); QString view; if ( mCurrentView == mWhatsNextView ) { view = QLatin1String( "WhatsNext" ); } else if ( mCurrentView == mListView ) { view = QLatin1String( "List" ); } else if ( mCurrentView == mJournalView ) { view = QLatin1String( "Journal" ); } else if ( mCurrentView == mTodoView ) { view = QLatin1String( "Todo" ); } else if ( mCurrentView == mTimelineView ) { view = QLatin1String( "Timeline" ); } else if ( mCurrentView == mTimeSpentView ) { view = QLatin1String( "TimeSpent" ); } else if ( mCurrentView == mMonthView ) { view = QLatin1String( "Month" ); } else { view = QLatin1String( "Agenda" ); } generalConfig.writeEntry( "Current View", view ); if ( mAgendaView ) { mAgendaView->writeSettings( config ); } if ( mListView ) { mListView->writeSettings( config ); } if ( mTodoView ) { mTodoView->saveLayout( config, QLatin1String("Todo View") ); } // write out custom view configuration Q_FOREACH ( KOrg::BaseView *const view, mViews ) { KConfigGroup group = KGlobal::config()->group( view->identifier() ); view->saveConfig( group ); } generalConfig.writeEntry( "Range Mode", int( mRangeMode ) ); } void KOViewManager::showView( KOrg::BaseView *view ) { if ( view == mCurrentView ) { return; } mCurrentView = view; mMainView->updateHighlightModes(); if ( mCurrentView && mCurrentView->isEventView() ) { mLastEventView = mCurrentView; } if ( mAgendaView ) { mAgendaView->deleteSelectedDateTime(); } raiseCurrentView(); mMainView->processIncidenceSelection( Akonadi::Item(), QDate() ); mMainView->updateView(); mMainView->adaptNavigationUnits(); KOrg::MainWindow *w = ActionManager::findInstance( KUrl() ); if ( w ) { KActionCollection *ac = w->getActionCollection(); if ( ac ) { if ( QAction *action = ac->action( QLatin1String("configure_view") ) ) { action->setEnabled( view->hasConfigurationDialog() ); } QStringList zoomActions; QStringList rangeActions; zoomActions << QLatin1String("zoom_in_horizontally") << QLatin1String("zoom_out_horizontally") << QLatin1String("zoom_in_vertically") << QLatin1String("zoom_out_vertically"); rangeActions << QLatin1String("select_workweek") - << QLatin1String("select_week") - << QLatin1String("select_day") << QLatin1String("select_nextx"); for ( int i = 0; i < zoomActions.size(); ++i ) { if ( QAction *action = ac->action( zoomActions[i] ) ) { action->setEnabled( view->supportsZoom() ); } } for ( int i = 0; i < rangeActions.size(); ++i ) { if ( QAction *action = ac->action( rangeActions[i] ) ) { action->setEnabled( view->supportsDateRangeSelection() ); } } } } } void KOViewManager::goMenu( bool enable ) { KOrg::MainWindow *w = ActionManager::findInstance( KUrl() ); if ( w ) { KActionCollection *ac = w->getActionCollection(); if ( ac ) { QAction *action; action = ac->action( QLatin1String("go_today") ); if ( action ) { action->setEnabled( enable ); } action = ac->action( QLatin1String("go_previous") ); if ( action ) { action->setEnabled( enable ); } action = ac->action( QLatin1String("go_next") ); if ( action ) { action->setEnabled( enable ); } } } } void KOViewManager::raiseCurrentView() { if ( mCurrentView && mCurrentView->usesFullWindow() ) { mMainView->showLeftFrame( false ); if ( mCurrentView == mTodoView ) { mMainView->navigatorBar()->hide(); } else { mMainView->navigatorBar()->show(); } } else { mMainView->showLeftFrame( true ); mMainView->navigatorBar()->hide(); } mMainView->viewStack()->setCurrentWidget( widgetForView( mCurrentView ) ); } void KOViewManager::updateView() { if ( mCurrentView ) { mCurrentView->updateView(); } } void KOViewManager::updateView( const QDate &start, const QDate &end, const QDate &preferredMonth ) { if ( mCurrentView && mCurrentView != mTodoView ) { mCurrentView->setDateRange( KDateTime( start ), KDateTime( end ), preferredMonth ); } else if ( mTodoView ) { mTodoView->updateView(); } } void KOViewManager::connectView( KOrg::BaseView *view ) { if ( !view ) { return; } if ( view->isEventView() ) { connect( view, SIGNAL(datesSelected(KCalCore::DateList)), SIGNAL(datesSelected(KCalCore::DateList)) ); } // selecting an incidence connect( view, SIGNAL(incidenceSelected(Akonadi::Item,QDate)), mMainView, SLOT(processMainViewSelection(Akonadi::Item,QDate)) ); // showing/editing/deleting an incidence. The calendar view takes care of the action. connect( view, SIGNAL(showIncidenceSignal(Akonadi::Item)), mMainView, SLOT(showIncidence(Akonadi::Item)) ); connect( view, SIGNAL(editIncidenceSignal(Akonadi::Item, KDateTime)), mMainView, SLOT(editIncidence(Akonadi::Item, KDateTime)) ); connect( view, SIGNAL(deleteIncidenceSignal(Akonadi::Item)), mMainView, SLOT(deleteIncidence(Akonadi::Item)) ); connect( view, SIGNAL(copyIncidenceSignal(Akonadi::Item)), mMainView, SLOT(copyIncidence(Akonadi::Item)) ); connect( view, SIGNAL(cutIncidenceSignal(Akonadi::Item)), mMainView, SLOT(cutIncidence(Akonadi::Item)) ); connect( view, SIGNAL(pasteIncidenceSignal()), mMainView, SLOT(pasteIncidence()) ); connect( view, SIGNAL(toggleAlarmSignal(Akonadi::Item)), mMainView, SLOT(toggleAlarm(Akonadi::Item)) ); connect( view, SIGNAL(toggleTodoCompletedSignal(Akonadi::Item)), mMainView, SLOT(toggleTodoCompleted(Akonadi::Item)) ); connect( view, SIGNAL(copyIncidenceToResourceSignal(Akonadi::Item,QString)), mMainView, SLOT(copyIncidenceToResource(Akonadi::Item,QString)) ); connect( view, SIGNAL(moveIncidenceToResourceSignal(Akonadi::Item,QString)), mMainView, SLOT(moveIncidenceToResource(Akonadi::Item,QString)) ); connect( view, SIGNAL(dissociateOccurrencesSignal(Akonadi::Item,QDate)), mMainView, SLOT(dissociateOccurrences(Akonadi::Item,QDate)) ); // signals to create new incidences connect( view, SIGNAL(newEventSignal()), mMainView, SLOT(newEvent()) ); connect( view, SIGNAL(newEventSignal(QDateTime)), mMainView, SLOT(newEvent(QDateTime)) ); connect( view, SIGNAL(newEventSignal(QDateTime,QDateTime)), mMainView, SLOT(newEvent(QDateTime,QDateTime)) ); connect( view, SIGNAL(newEventSignal(QDate)), mMainView, SLOT(newEvent(QDate)) ); connect( view, SIGNAL(newTodoSignal(QDate)), mMainView, SLOT(newTodo(QDate)) ); connect( view, SIGNAL(newSubTodoSignal(Akonadi::Item)), mMainView, SLOT(newSubTodo(Akonadi::Item)) ); connect( view, SIGNAL(newJournalSignal(QDate)), mMainView, SLOT(newJournal(QDate)) ); // reload settings connect( mMainView, SIGNAL(configChanged()), view, SLOT(updateConfig()) ); // Notifications about added, changed and deleted incidences connect( mMainView, SIGNAL(dayPassed(QDate)), view, SLOT(dayPassed(QDate)) ); connect( view, SIGNAL(startMultiModify(QString)), mMainView, SLOT(startMultiModify(QString)) ); connect( view, SIGNAL(endMultiModify()), mMainView, SLOT(endMultiModify()) ); connect( mMainView, SIGNAL(newIncidenceChanger(Akonadi::IncidenceChanger*)), view, SLOT(setIncidenceChanger(Akonadi::IncidenceChanger*)) ); view->setIncidenceChanger( mMainView->incidenceChanger() ); } void KOViewManager::connectTodoView( KOTodoView *todoView ) { if ( !todoView ) { return; } // SIGNALS/SLOTS FOR TODO VIEW connect( todoView, SIGNAL(purgeCompletedSignal()), mMainView, SLOT(purgeCompleted()) ); connect( todoView, SIGNAL(unSubTodoSignal()), mMainView, SLOT(todo_unsub()) ); connect( todoView, SIGNAL(unAllSubTodoSignal()), mMainView, SLOT(makeSubTodosIndependent()) ); connect( todoView, SIGNAL(fullViewChanged(bool)), mMainView, SLOT(changeFullView(bool)) ); } void KOViewManager::zoomInHorizontally() { if ( mAgendaView == mCurrentView ) { mAgendaView->zoomInHorizontally(); } } void KOViewManager::zoomOutHorizontally() { if ( mAgendaView == mCurrentView ) { mAgendaView->zoomOutHorizontally(); } } void KOViewManager::zoomInVertically() { if ( mAgendaView == mCurrentView ) { mAgendaView->zoomInVertically(); } } void KOViewManager::zoomOutVertically() { if ( mAgendaView == mCurrentView ) { mAgendaView->zoomOutVertically(); } } void KOViewManager::addView( KOrg::BaseView *view, bool isTab ) { connectView( view ); mViews.append( view ); const KConfigGroup group = KGlobal::config()->group( view->identifier() ); view->restoreConfig( group ); if ( !isTab ) { mMainView->viewStack()->addWidget( view ); } } void KOViewManager::showTimeSpentView() { if ( !mTimeSpentView ) { mTimeSpentView = new KOTimeSpentView( mMainView->viewStack() ); mTimeSpentView->setCalendar( mMainView->calendar() ); mTimeSpentView->setIdentifier( "DefaultTimeSpentView" ); addView( mTimeSpentView ); } goMenu( true ); showView( mTimeSpentView ); } void KOViewManager::showMonthView() { if ( !mMonthView ) { mMonthView = new KOrg::MonthView( mMainView->viewStack() ); mMonthView->setCalendar( mMainView->calendar() ); mMonthView->setIdentifier( "DefaultMonthView" ); addView( mMonthView ); connect( mMonthView, SIGNAL(fullViewChanged(bool)), mMainView, SLOT(changeFullView(bool)) ); } goMenu( true ); showView( mMonthView ); } void KOViewManager::showWhatsNextView() { if ( !mWhatsNextView ) { mWhatsNextView = new KOWhatsNextView( mMainView->viewStack() ); mWhatsNextView->setCalendar( mMainView->calendar() ); mWhatsNextView->setIdentifier( "DefaultWhatsNextView" ); addView( mWhatsNextView ); } goMenu( true ); showView( mWhatsNextView ); } void KOViewManager::showListView() { if ( !mListView ) { mListView = new KOListView( mMainView->calendar(), mMainView->viewStack() ); mListView->setIdentifier( "DefaultListView" ); addView( mListView ); } goMenu( true ); showView( mListView ); } void KOViewManager::showAgendaView() { const bool showBoth = KOPrefs::instance()->agendaViewCalendarDisplay() == KOPrefs::AllCalendarViews; const bool showMerged = showBoth || KOPrefs::instance()->agendaViewCalendarDisplay() == KOPrefs::CalendarsMerged; const bool showSideBySide = showBoth || KOPrefs::instance()->agendaViewCalendarDisplay() == KOPrefs::CalendarsSideBySide; QWidget *parent = mMainView->viewStack(); if ( showBoth ) { if ( !mAgendaViewTabs && showBoth ) { mAgendaViewTabs = new KTabWidget( mMainView->viewStack() ); connect( mAgendaViewTabs, SIGNAL(currentChanged(QWidget*)), this, SLOT(currentAgendaViewTabChanged(QWidget*)) ); mMainView->viewStack()->addWidget( mAgendaViewTabs ); KConfig *config = KOGlobals::self()->config(); KConfigGroup viewConfig( config, "Views" ); mAgendaViewTabIndex = viewConfig.readEntry( "Agenda View Tab Index", 0 ); } parent = mAgendaViewTabs; } if ( showMerged ) { if ( !mAgendaView ) { mAgendaView = new KOAgendaView( parent ); mAgendaView->setCalendar( mMainView->calendar() ); mAgendaView->setIdentifier( "DefaultAgendaView" ); addView( mAgendaView, showBoth ); connect( mAgendaView,SIGNAL(zoomViewHorizontally(QDate,int)), mMainView->dateNavigator(), SLOT(selectDates(QDate,int)) ); mAgendaView->readSettings( KOGlobals::self()->config() ); } if ( showBoth && mAgendaViewTabs->indexOf( mAgendaView ) < 0 ) { mAgendaViewTabs->addTab( mAgendaView, i18n( "Merged calendar" ) ); } else if ( !showBoth && mMainView->viewStack()->indexOf( mAgendaView ) < 0 ) { mAgendaView->setParent( parent ); mMainView->viewStack()->addWidget( mAgendaView ); } } if ( showSideBySide ) { if ( !mAgendaSideBySideView ) { mAgendaSideBySideView = new MultiAgendaView( parent ); mAgendaSideBySideView->setIdentifier( "DefaultAgendaSideBySideView" ); mAgendaSideBySideView->setCalendar( mMainView->calendar() ); addView( mAgendaSideBySideView, showBoth ); /* connect( mAgendaSideBySideView,SIGNAL(zoomViewHorizontally(QDate,int)), mMainView->dateNavigator(),SLOT(selectDates(QDate,int)) );*/ } if ( showBoth && mAgendaViewTabs->indexOf( mAgendaSideBySideView ) < 0 ) { mAgendaViewTabs->addTab( mAgendaSideBySideView, i18n( "Calendars Side by Side" ) ); mAgendaViewTabs->setCurrentIndex( mAgendaViewTabIndex ); } else if ( !showBoth && mMainView->viewStack()->indexOf( mAgendaSideBySideView ) < 0 ) { mAgendaSideBySideView->setParent( parent ); mMainView->viewStack()->addWidget( mAgendaSideBySideView ); } } goMenu( true ); if ( showBoth ) { showView( static_cast( mAgendaViewTabs->currentWidget() ) ); } else if ( showMerged ) { showView( mAgendaView ); } else if ( showSideBySide ) { showView( mAgendaSideBySideView ); } } void KOViewManager::selectDay() { + showAgendaView(); mRangeMode = DAY_RANGE; const QDate date = mMainView->activeDate(); mMainView->dateNavigator()->selectDate( date ); } void KOViewManager::selectWorkWeek() { if ( KOGlobals::self()->getWorkWeekMask() != 0 ) { mRangeMode = WORK_WEEK_RANGE; QDate date = mMainView->activeDate(); mMainView->dateNavigator()->selectWorkWeek( date ); } else { KMessageBox::sorry( mMainView, i18n( "Unable to display the work week since there are no work days configured. " "Please properly configure at least 1 work day in the Time and Date preferences." ) ); } } void KOViewManager::selectWeek() { + showAgendaView(); mRangeMode = WEEK_RANGE; QDate date = mMainView->activeDate(); mMainView->dateNavigator()->selectWeek( date ); } void KOViewManager::selectNextX() { mRangeMode = NEXTX_RANGE; mMainView->dateNavigator()->selectDates( QDate::currentDate(), KOPrefs::instance()->mNextXDays ); } void KOViewManager::showTodoView() { if ( !mTodoView ) { mTodoView = new KOTodoView( false/*not sidebar*/, mMainView->viewStack() ); mTodoView->setCalendar( mMainView->calendar() ); mTodoView->setIdentifier( "DefaultTodoView" ); mTodoView->setCalendar( mMainView->calendar() ); addView( mTodoView ); connectTodoView( mTodoView ); KConfig *config = KOGlobals::self()->config(); mTodoView->restoreLayout( config, QLatin1String("Todo View"), false ); } goMenu( false ); showView( mTodoView ); } void KOViewManager::showJournalView() { if ( !mJournalView ) { mJournalView = new KOJournalView( mMainView->viewStack() ); mJournalView->setCalendar( mMainView->calendar() ); mJournalView->setIdentifier( "DefaultJournalView" ); addView( mJournalView ); } goMenu( true ); showView( mJournalView ); } void KOViewManager::showTimeLineView() { if ( !mTimelineView ) { mTimelineView = new KOTimelineView( mMainView->viewStack() ); mTimelineView->setCalendar( mMainView->calendar() ); mTimelineView->setIdentifier( "DefaultTimelineView" ); addView( mTimelineView ); } goMenu( true ); showView( mTimelineView ); } void KOViewManager::showEventView() { if ( mLastEventView ) { goMenu( true ); showView( mLastEventView ); } else { showAgendaView(); selectWeek(); } } Akonadi::Item KOViewManager::currentSelection() { if ( !mCurrentView ) { return Akonadi::Item(); } Akonadi::Item::List incidenceList = mCurrentView->selectedIncidences(); if ( incidenceList.isEmpty() ) { return Akonadi::Item(); } return incidenceList.first(); } QDate KOViewManager::currentSelectionDate() { QDate qd; if ( mCurrentView ) { KCalCore::DateList qvl = mCurrentView->selectedIncidenceDates(); if ( !qvl.isEmpty() ) { qd = qvl.first(); } } return qd; } void KOViewManager::setDocumentId( const QString &id ) { if ( mTodoView ) { mTodoView->setDocumentId( id ); } } QWidget *KOViewManager::widgetForView( KOrg::BaseView *view ) const { if ( mAgendaViewTabs && mAgendaViewTabs->indexOf( view ) >= 0 ) { return mAgendaViewTabs; } return view; } void KOViewManager::currentAgendaViewTabChanged( QWidget *widget ) { KConfig *config = KOGlobals::self()->config(); KConfigGroup viewConfig( config, "Views" ); viewConfig.writeEntry( "Agenda View Tab Index", mAgendaViewTabs->currentIndex() ); if ( widget ) { goMenu( true ); showView( static_cast( widget ) ); } } void KOViewManager::addChange( EventViews::EventView::Change change ) { foreach ( BaseView *view, mViews ) { if ( view ) { view->setChanges( view->changes() | change ); } } } void KOViewManager::updateMultiCalendarDisplay() { if ( agendaIsSelected() ) { showAgendaView(); } else { updateView(); } } bool KOViewManager::agendaIsSelected() const { return mCurrentView == mAgendaView || mCurrentView == mAgendaSideBySideView || ( mAgendaViewTabs && mCurrentView == mAgendaViewTabs->currentWidget() ); }