24#include "alarmcalendar.h" 
   26#include "alarmlistview.h" 
   32#include "preferences.h" 
   33#include "shellprocess.h" 
   34#include "templatelistview.h" 
   35#include "templatemenuaction.h" 
   37#include <tqdeepcopy.h> 
   45#include <kstdguiitem.h> 
   46#include <tdestdaccel.h> 
   47#include <tdemessagebox.h> 
   48#include <tdefiledialog.h> 
   49#include <dcopclient.h> 
   51#include <kdcopservicestarter.h> 
   54#include <libkcal/event.h> 
   55#include <libkcal/icalformat.h> 
   56#include <libkpimidentities/identitymanager.h> 
   57#include <libkpimidentities/identity.h> 
   58#include <libkcal/person.h> 
   63bool        resetDaemonQueued = 
false;
 
   64TQCString   korganizerName = 
"korganizer";
 
   65TQString    korgStartError;
 
   66#define     KORG_DCOP_OBJECT    "KOrganizerIface" 
   68const char* KMAIL_DCOP_WINDOW = 
"kmail-mainwindow#1";
 
   70bool sendToKOrganizer(
const KAEvent&);
 
   71bool deleteFromKOrganizer(
const TQString& eventID);
 
   82MainWindow* displayMainWindowSelected(
const TQString& eventID)
 
   84    MainWindow* win = MainWindow::firstWindow();
 
   87        if (theApp()->checkCalendarDaemon())    
 
   89            win = MainWindow::create();
 
   96        bool visible = win->isVisible();
 
   99        if (!visible  ||  win->isMinimized())
 
  102        win->setActiveWindow();
 
  104    if (win  &&  !eventID.isEmpty())
 
  105        win->selectEvent(eventID);
 
  112TDEAction* createNewAlarmAction(
const TQString& label, TQObject* receiver, 
const char* slot, TDEActionCollection* actions, 
const char* name)
 
  114    return new TDEAction(label, 
"document-new", TDEStdAccel::openNew(), receiver, slot, actions, name);
 
  120TemplateMenuAction* createNewFromTemplateAction(
const TQString& label, TQObject* receiver, 
const char* slot, TDEActionCollection* actions, 
const char* name)
 
  122    return new TemplateMenuAction(label, 
"new_from_template", receiver, slot, actions, name);
 
  132UpdateStatus addEvent(
KAEvent& event, AlarmListView* selectionView, TQWidget* errmsgParent, 
bool useEventID, 
bool allowKOrgUpdate)
 
  134    kdDebug(5950) << 
"KAlarm::addEvent(): " << 
event.id() << endl;
 
  136    if (!theApp()->checkCalendarDaemon())    
 
  137        return UPDATE_FAILED;
 
  142        if (!cal->addEvent(event, useEventID))
 
  143            status = UPDATE_FAILED;
 
  144        else if (!cal->save())
 
  145            status = SAVE_FAILED;
 
  147    if (status == UPDATE_OK)
 
  149        if (allowKOrgUpdate  &&  event.copyToKOrganizer())
 
  151            if (!sendToKOrganizer(event))    
 
  152                status = UPDATE_KORG_ERR;
 
  156        AlarmListView::addEvent(event, selectionView);
 
  161        displayUpdateError(errmsgParent, status, ERR_ADD, 1);
 
  169bool addExpiredEvent(
KAEvent& event)
 
  171    kdDebug(5950) << 
"KAlarm::addExpiredEvent(" << 
event.id() << 
")\n";
 
  175    bool archiving = (KAEvent::uidStatus(event.id()) == KAEvent::ACTIVE);
 
  177        event.setSaveDateTime(TQDateTime::currentDateTime());   
 
  183        AlarmListView::addEvent(event, 0);
 
  185        AlarmListView::modifyEvent(
KAEvent(*kcalEvent), 0);
 
  196UpdateStatus addTemplate(
KAEvent& event, TemplateListView* selectionView, TQWidget* errmsgParent)
 
  198    kdDebug(5950) << 
"KAlarm::addTemplate(): " << 
event.id() << endl;
 
  203    if (!cal  ||  !cal->addEvent(event))
 
  204        status = UPDATE_FAILED;
 
  205    else if (!cal->save())
 
  206        status = SAVE_FAILED;
 
  209        cal->emitEmptyStatus();
 
  212        TemplateListView::addEvent(event, selectionView);
 
  217        displayUpdateError(errmsgParent, status, ERR_TEMPLATE, 1);
 
  230    kdDebug(5950) << 
"KAlarm::modifyEvent(): '" << oldEvent.id() << endl;
 
  233    if (!newEvent.valid())
 
  235        deleteEvent(oldEvent, 
true);
 
  236        status = UPDATE_FAILED;
 
  240        if (oldEvent.copyToKOrganizer())
 
  245            deleteFromKOrganizer(oldEvent.id());
 
  250        if (!cal->deleteEvent(oldEvent.id())
 
  251        ||  !cal->addEvent(
const_cast<KAEvent&
>(newEvent), 
true))
 
  252            status = UPDATE_FAILED;
 
  253        else if (!cal->save())
 
  254            status = SAVE_FAILED;
 
  255        if (status == UPDATE_OK)
 
  257            if (newEvent.copyToKOrganizer())
 
  259                if (!sendToKOrganizer(newEvent))    
 
  260                    status = UPDATE_KORG_ERR;
 
  264            AlarmListView::modifyEvent(oldEvent.id(), newEvent, selectionView);
 
  270        displayUpdateError(errmsgParent, status, ERR_ADD, 1);
 
  283UpdateStatus updateEvent(
KAEvent& event, AlarmListView* selectionView, TQWidget* errmsgParent, 
bool archiveOnDelete, 
bool incRevision)
 
  285    kdDebug(5950) << 
"KAlarm::updateEvent(): " << 
event.id() << endl;
 
  288        deleteEvent(event, archiveOnDelete);
 
  293            event.incrementRevision();    
 
  295        cal->updateEvent(event);
 
  299                displayUpdateError(errmsgParent, SAVE_FAILED, ERR_ADD, 1);
 
  304        AlarmListView::modifyEvent(event, selectionView);
 
  314UpdateStatus updateTemplate(
const KAEvent& event, TemplateListView* selectionView, TQWidget* errmsgParent)
 
  319        status = UPDATE_FAILED;
 
  322        cal->updateEvent(event);
 
  324            status = SAVE_FAILED;
 
  327            TemplateListView::modifyEvent(event.id(), event, selectionView);
 
  333        displayUpdateError(errmsgParent, SAVE_FAILED, ERR_TEMPLATE, 1);
 
  343    TQString 
id = 
event.id();
 
  344    kdDebug(5950) << 
"KAlarm::deleteEvent(): " << 
id << endl;
 
  347    AlarmListView::deleteEvent(
id);
 
  353    if (KAEvent::uidStatus(
id) == KAEvent::EXPIRED)
 
  355        cal = AlarmCalendar::expiredCalendarOpen();
 
  357            status = UPDATE_FAILED;
 
  361        if (event.copyToKOrganizer())
 
  366            if (!deleteFromKOrganizer(event.id()))
 
  367                status = UPDATE_KORG_ERR;
 
  369        if (archive  &&  event.toBeArchived())
 
  370            addExpiredEvent(event);     
 
  371        cal = AlarmCalendar::activeCalendar();
 
  373    if (status != UPDATE_FAILED)
 
  375        if (!cal->deleteEvent(
id, 
true))   
 
  376            status = SAVE_FAILED;
 
  378    if (status > UPDATE_KORG_ERR  &&  errmsgParent)
 
  379        displayUpdateError(errmsgParent, SAVE_FAILED, ERR_DELETE, 1);
 
  388    TQString 
id = 
event.id();
 
  393        return UPDATE_FAILED;
 
  394    if (!cal->deleteEvent(
id, 
true))    
 
  396    cal->emitEmptyStatus();
 
  399    TemplateListView::deleteEvent(
id);
 
  406void deleteDisplayEvent(
const TQString& eventID)
 
  408    kdDebug(5950) << 
"KAlarm::deleteDisplayEvent(" << eventID << 
")\n";
 
  410    if (KAEvent::uidStatus(eventID) == KAEvent::DISPLAYING)
 
  414            cal->deleteEvent(eventID, 
true);   
 
  426    TQString 
id = 
event.id();
 
  427    kdDebug(5950) << 
"KAlarm::reactivateEvent(): " << 
id << endl;
 
  430    if (KAEvent::uidStatus(
id) == KAEvent::EXPIRED)
 
  432        TQDateTime now = TQDateTime::currentDateTime();
 
  433        if (event.occursAfter(now, 
true))
 
  435            if (event.recurs()  ||  event.repeatCount())
 
  436                event.setNextOccurrence(now);   
 
  441            if (!cal->addEvent(event, useEventID))
 
  442                return UPDATE_FAILED;
 
  447            if (event.copyToKOrganizer())
 
  449                if (!sendToKOrganizer(event))    
 
  450                    status = UPDATE_KORG_ERR;
 
  454            AlarmListView::undeleteEvent(
id, event, selectionView);
 
  456            cal = AlarmCalendar::expiredCalendarOpen();
 
  458                cal->deleteEvent(
id, 
true);   
 
  462    return UPDATE_FAILED;
 
  473    kdDebug(5950) << 
"KAlarm::enableEvent(" << enable << 
"): " << 
event.id() << endl;
 
  475    if (enable != event.enabled())
 
  477        event.setEnabled(enable);
 
  481        cal->updateEvent(event);
 
  486        if (!enable  &&  event.displayAction())
 
  488            MessageWin* win = MessageWin::findEvent(event.id());
 
  493        AlarmListView::modifyEvent(event, selectionView);
 
  501void displayUpdateError(TQWidget* parent, UpdateStatus, UpdateError code, 
int nAlarms)
 
  507            errmsg = (nAlarms > 1) ? i18n(
"Error saving alarms")
 
  508                                   : i18n(
"Error saving alarm");
 
  511            errmsg = (nAlarms > 1) ? i18n(
"Error deleting alarms")
 
  512                                   : i18n(
"Error deleting alarm");
 
  515            errmsg = (nAlarms > 1) ? i18n(
"Error saving reactivated alarms")
 
  516                                   : i18n(
"Error saving reactivated alarm");
 
  519            errmsg = i18n(
"Error saving alarm template");
 
  522    KMessageBox::error(parent, errmsg);
 
  528void displayKOrgUpdateError(TQWidget* parent, KOrgUpdateError code, 
int nAlarms)
 
  534            errmsg = (nAlarms > 1) ? i18n(
"Unable to show alarms in KOrganizer")
 
  535                                   : i18n(
"Unable to show alarm in KOrganizer");
 
  537        case KORG_ERR_MODIFY:
 
  538            errmsg = i18n(
"Unable to update alarm in KOrganizer");
 
  540        case KORG_ERR_DELETE:
 
  541            errmsg = (nAlarms > 1) ? i18n(
"Unable to delete alarms from KOrganizer")
 
  542                                   : i18n(
"Unable to delete alarm from KOrganizer");
 
  545    KMessageBox::error(parent, errmsg);
 
  551bool edit(
const TQString& eventID)
 
  554    switch (KAEvent::uidStatus(eventID))
 
  556        case KAEvent::ACTIVE:
 
  557            cal = AlarmCalendar::activeCalendar();
 
  559        case KAEvent::TEMPLATE:
 
  560            cal = AlarmCalendar::templateCalendarOpen();
 
  563            kdError(5950) << 
"KAlarm::edit(" << eventID << 
"): event not active or template" << endl;
 
  569        kdError(5950) << 
"KAlarm::edit(): event ID not found: " << eventID << endl;
 
  573    MainWindow::executeEdit(event);
 
  581bool editNew(
const TQString& templateName)
 
  584    if (!templateName.isEmpty())
 
  589            KAEvent templateEvent = KAEvent::findTemplateName(*cal, templateName);
 
  590            if (templateEvent.valid())
 
  592                MainWindow::executeNew(templateEvent);
 
  595            kdWarning(5950) << 
"KAlarm::editNew(" << templateName << 
"): template not found" << endl;
 
  599    MainWindow::executeNew();
 
  607TQValueList<KAEvent> templateList()
 
  609    TQValueList<KAEvent> templates;
 
  613        bool includeCmdAlarms = ShellProcess::authorised();
 
  614        KCal::Event::List events = cal->events();
 
  615        for (KCal::Event::List::ConstIterator it = events.begin();  it != events.end();  ++it)
 
  619            if (includeCmdAlarms  ||  event.action() != KAEvent::COMMAND)
 
  620                templates.append(event);
 
  631void outputAlarmWarnings(TQWidget* parent, 
const KAEvent* event)
 
  633    if (event  &&  event->action() == KAEvent::EMAIL
 
  634    &&  Preferences::emailAddress().isEmpty())
 
  635        KMessageBox::information(parent, i18n(
"Please set the 'From' email address...",
 
  636                                              "%1\nPlease set it in the Preferences dialog.").arg(KAMail::i18n_NeedFromEmailAddress()));
 
  638    if (!Daemon::monitoringAlarms())
 
  640        if (KMessageBox::warningYesNo(parent, i18n(
"Alarms are currently disabled.\nDo you want to enable alarms now?"),
 
  641                                      TQString(), i18n(
"Enable"), i18n(
"Keep Disabled"),
 
  642                                      TQString::fromLatin1(
"EditEnableAlarms"))
 
  644            Daemon::setAlarmsEnabled();
 
  654    kdDebug(5950) << 
"KAlarm::resetDaemon()" << endl;
 
  655    if (!resetDaemonQueued)
 
  657        resetDaemonQueued = 
true;
 
  658        theApp()->processQueue();
 
  669void resetDaemonIfQueued()
 
  671    if (resetDaemonQueued)
 
  673        kdDebug(5950) << 
"KAlarm::resetDaemonIfNeeded()" << endl;
 
  674        AlarmCalendar::activeCalendar()->reload();
 
  675        AlarmCalendar::expiredCalendar()->reload();
 
  679        KCal::Event::List events = AlarmCalendar::activeCalendar()->events();
 
  680        for (KCal::Event::List::ConstIterator it = events.begin();  it != events.end();  ++it)
 
  683            event.set(*kcalEvent);
 
  684            if (!event.enabled()  &&  event.displayAction())
 
  686                MessageWin* win = MessageWin::findEvent(event.id());
 
  691        MainWindow::refresh();
 
  692        if (!Daemon::reset())
 
  694        resetDaemonQueued = 
false;
 
  703TQString runKMail(
bool minimise)
 
  707    if (!runProgram(
"kmail", (minimise ? KMAIL_DCOP_WINDOW : 
""), dcopName, errmsg))
 
  708        return i18n(
"Unable to start KMail\n(%1)").arg(errmsg);
 
  719bool runProgram(
const TQCString& program, 
const TQCString& windowName, TQCString& dcopName, TQString& errorMessage)
 
  721    if (!tdeApp->dcopClient()->isApplicationRegistered(program))
 
  724        if (TDEApplication::startServiceByDesktopName(TQString::fromLatin1(program), TQString(), &errorMessage, &dcopName))
 
  726            kdError(5950) << 
"runProgram(): couldn't start " << program << 
" (" << errorMessage << 
")\n";
 
  732        tdeApp->dcopClient()->send(dcopName, windowName, 
"minimize()", TQString());
 
  734    else if (dcopName.isEmpty())
 
  736    errorMessage = TQString();
 
  746bool readConfigWindowSize(
const char* window, TQSize& result)
 
  748    TDEConfig* config = TDEGlobal::config();
 
  749    config->setGroup(TQString::fromLatin1(window));
 
  750    TQWidget* desktop = TDEApplication::desktop();
 
  751    TQSize s = TQSize(config->readNumEntry(TQString::fromLatin1(
"Width %1").arg(desktop->width()), 0),
 
  752                    config->readNumEntry(TQString::fromLatin1(
"Height %1").arg(desktop->height()), 0));
 
  763void writeConfigWindowSize(
const char* window, 
const TQSize& size)
 
  765    TDEConfig* config = TDEGlobal::config();
 
  766    config->setGroup(TQString::fromLatin1(window));
 
  767    TQWidget* desktop = TDEApplication::desktop();
 
  768    config->writeEntry(TQString::fromLatin1(
"Width %1").arg(desktop->width()), size.width());
 
  769    config->writeEntry(TQString::fromLatin1(
"Height %1").arg(desktop->height()), size.height());
 
  778    static int version = 0;
 
  780        version = getVersionNumber(KALARM_VERSION);
 
  790int getVersionNumber(
const TQString& version, TQString* subVersion)
 
  795        *subVersion = TQString();
 
  796    int count = version.contains(
'.') + 1;
 
  800    unsigned vernum = version.section(
'.', 0, 0).toUInt(&ok) * 10000;  
 
  803    unsigned v = version.section(
'.', 1, 1).toUInt(&ok);               
 
  806    vernum += (v < 99 ? v : 99) * 100;
 
  810        TQString issue = version.section(
'.', 2);
 
  811        if (!issue.at(0).isDigit())
 
  813        int n = issue.length();
 
  815        for (i = 0;  i < n && issue.at(i).isDigit();  ++i) ;
 
  817            *subVersion = issue.mid(i);
 
  818        v = issue.left(i).toUInt();   
 
  819        vernum += (v < 99 ? v : 99);
 
  829FileType fileType(
const TQString& mimetype)
 
  831    static const char* applicationTypes[] = {
 
  832        "x-shellscript", 
"x-nawk", 
"x-awk", 
"x-perl", 
"x-python",
 
  833        "x-desktop", 
"x-troff", 0 };
 
  834    static const char* formattedTextTypes[] = {
 
  837    if (mimetype.startsWith(TQString::fromLatin1(
"image/")))
 
  839    int slash = mimetype.find(
'/');
 
  842    TQString type = mimetype.mid(slash + 1);
 
  843    const char* typel = type.latin1();
 
  844    if (mimetype.startsWith(TQString::fromLatin1(
"application")))
 
  846        for (
int i = 0;  applicationTypes[i];  ++i)
 
  847            if (!strcmp(typel, applicationTypes[i]))
 
  848                return TextApplication;
 
  850    else if (mimetype.startsWith(TQString::fromLatin1(
"text")))
 
  852        for (
int i = 0;  formattedTextTypes[i];  ++i)
 
  853            if (!strcmp(typel, formattedTextTypes[i]))
 
  854                return TextFormatted;
 
  870TQString browseFile(
const TQString& caption, TQString& defaultDir, 
const TQString& initialFile,
 
  871                   const TQString& filter, 
int mode, TQWidget* parent, 
const char* name)
 
  873    TQString initialDir = !initialFile.isEmpty() ? TQString(initialFile).remove(TQRegExp(
"/[^/]*$"))
 
  874                       : !defaultDir.isEmpty()  ? defaultDir
 
  875                       :                          TQDir::homeDirPath();
 
  876    KFileDialog fileDlg(initialDir, filter, parent, name, 
true);
 
  877    fileDlg.setOperationMode(mode & KFile::ExistingOnly ? KFileDialog::Opening : KFileDialog::Saving);
 
  878    fileDlg.setMode(KFile::File | mode);
 
  879    fileDlg.setCaption(caption);
 
  880    if (!initialFile.isEmpty())
 
  881        fileDlg.setSelection(initialFile);
 
  882    if (fileDlg.exec() != TQDialog::Accepted)
 
  884    KURL url = fileDlg.selectedURL();
 
  885    defaultDir = url.path();
 
  886    return (mode & KFile::LocalOnly) ? url.path() : url.prettyURL();
 
  893int localeFirstDayOfWeek()
 
  895    static int firstDay = 0;
 
  897        firstDay = TDEGlobal::locale()->weekStartDay();
 
  904TQString stripAccel(
const TQString& text)
 
  906    unsigned len = text.length();
 
  907    TQString out = TQDeepCopy<TQString>(text);
 
  908    TQChar *corig = (TQChar*)out.unicode();
 
  909    TQChar *cout  = corig;
 
  925    unsigned newlen = cout - corig;
 
  926    if (newlen != out.length())
 
  927        out.truncate(newlen);
 
  941bool sendToKOrganizer(
const KAEvent& event)
 
  944    TQString uid = KAEvent::uid(event.id(), KAEvent::KORGANIZER);
 
  948    switch (event.action())
 
  950        case KAEvent::MESSAGE:
 
  952        case KAEvent::COMMAND:
 
  954            userEmail = Preferences::emailAddress();
 
  958            TQString from = 
event.emailFromId()
 
  959                         ? KAMail::identityManager()->identityForUoid(event.emailFromId()).fullEmailAddr()
 
  960                         : Preferences::emailAddress();
 
  962            atext.setEmail(event.emailAddresses(
", "), from, TQString(), TQString(), event.emailSubject(), TQString());
 
  974kdDebug(5950)<<
"Korg->"<<iCal<<endl;
 
  978    if (!runKOrganizer())     
 
  980    TQByteArray  data, replyData;
 
  982    TQDataStream arg(data, IO_WriteOnly);
 
  984    if (tdeApp->dcopClient()->call(korganizerName, KORG_DCOP_OBJECT, 
"addIncidence(TQString)", data, replyType, replyData)
 
  985    &&  replyType == 
"bool")
 
  988        TQDataStream reply(replyData, IO_ReadOnly);
 
  992            kdDebug(5950) << 
"sendToKOrganizer(" << uid << 
"): success\n";
 
  996    kdError(5950) << 
"sendToKOrganizer(): KOrganizer addEvent(" << uid << 
") dcop call failed\n";
 
 1003bool deleteFromKOrganizer(
const TQString& eventID)
 
 1005    if (!runKOrganizer())     
 
 1007    TQString newID = KAEvent::uid(eventID, KAEvent::KORGANIZER);
 
 1008    TQByteArray  data, replyData;
 
 1009    TQCString    replyType;
 
 1010    TQDataStream arg(data, IO_WriteOnly);
 
 1011    arg << newID << 
true;
 
 1012    if (tdeApp->dcopClient()->call(korganizerName, KORG_DCOP_OBJECT, 
"deleteIncidence(TQString,bool)", data, replyType, replyData)
 
 1013    &&  replyType == 
"bool")
 
 1016        TQDataStream reply(replyData, IO_ReadOnly);
 
 1020            kdDebug(5950) << 
"deleteFromKOrganizer(" << newID << 
"): success\n";
 
 1024    kdError(5950) << 
"sendToKOrganizer(): KOrganizer deleteEvent(" << newID << 
") dcop call failed\n";
 
 1034    TQCString dcopService;
 
 1035    int result = KDCOPServiceStarter::self()->findServiceFor(
"DCOP/Organizer", TQString(), TQString(), &error, &dcopService);
 
 1038        kdDebug(5950) << 
"Unable to start DCOP/Organizer: " << dcopService << 
" " << error << endl;
 
 1045    if (!tdeApp->dcopClient()->findObject(dcopService, KORG_DCOP_OBJECT, 
"", TQByteArray(), dummy, dummy))
 
 1047        DCOPRef ref(dcopService, dcopService); 
 
 1048        DCOPReply reply = ref.call(
"load()");
 
 1049        if (!reply.isValid() || !(
bool)reply)
 
 1051            kdWarning(5950) << 
"Error loading " << dcopService << endl;
 
 1054        if (!tdeApp->dcopClient()->findObject(dcopService, KORG_DCOP_OBJECT, 
"", TQByteArray(), dummy, dummy))
 
 1056            kdWarning(5950) << 
"Unable to access KOrganizer's " KORG_DCOP_OBJECT 
" DCOP object" << endl;
 
 1066#include <X11/keysym.h> 
 1067#include <X11/extensions/XTest.h> 
 1068#include <tqwindowdefs.h> 
 1074void x11_cancelScreenSaver()
 
 1076    kdDebug(5950) << 
"KAlarm::cancelScreenSaver()" << endl;
 
 1077    Display* display = tqt_xdisplay();
 
 1078    static int XTestKeyCode = 0;
 
 1080        XTestKeyCode = XKeysymToKeycode(display, XK_Shift_L);
 
 1081    XTestFakeKeyEvent(display, XTestKeyCode, 
true, CurrentTime);
 
 1082    XTestFakeKeyEvent(display, XTestKeyCode, 
false, CurrentTime);
 
 1083    XSync(display, 
false);
 
represents calendar alarms and events
 
Provides read and write access to calendar files.
 
KAEvent corresponds to a KCal::Event instance.
 
void setOrganizer(const Person &o)
 
void setUid(const TQString &)
 
void setSummary(const TQString &summary)
 
MessageWin: A window to display an alarm message.
 
UpdateStatus
Return codes from calendar update functions.
 
FileType
Return codes from fileType()
 
the KAlarm application object
 
displays an alarm message