konsolekalendar

main.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002  * main.cpp                                                                    *
00003  *                                                                             *
00004  * KonsoleKalendar is a command line interface to KDE calendars                *
00005  * Copyright (C) 2002-2004  Tuukka Pasanen <illuusio@mailcity.com>             *
00006  * Copyright (C) 2003-2005  Allen Winter <winter@kde.org>                      *
00007  *                                                                             *
00008  * This program is free software; you can redistribute it and/or modify        *
00009  * it under the terms of the GNU General Public License as published by        *
00010  * the Free Software Foundation; either version 2 of the License, or           *
00011  * (at your option) any later version.                                         *
00012  *                                                                             *
00013  * This program is distributed in the hope that it will be useful,             *
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of              *
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the                *
00016  * GNU General Public License for more details.                                *
00017  *                                                                             *
00018  * You should have received a copy of the GNU General Public License           *
00019  * along with this program; if not, write to the Free Software                 *
00020  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
00021  *                                                                             *
00022  * As a special exception, permission is given to link this program            *
00023  * with any edition of Qt, and distribute the resulting executable,            *
00024  * without including the source code for Qt in the source distribution.        *
00025  *                                                                             *
00026  ******************************************************************************/
00033 #ifdef HAVE_CONFIG_H
00034 #include "config.h"
00035 #endif
00036 
00037 #if TIME_WITH_SYS_TIME
00038 # include <sys/time.h>
00039 # include <time.h>
00040 #else
00041 # if HAVE_SYS_TIME_H
00042 #  include <sys/time.h>
00043 # else
00044 #  include <time.h>
00045 # endif
00046 #endif
00047 
00048 #include <kcmdlineargs.h>
00049 #include <kaboutdata.h>
00050 #include <klocale.h>
00051 #include <kglobal.h>
00052 #include <kconfig.h>
00053 #include <kstandarddirs.h>
00054 #include <kdebug.h>
00055 
00056 #include <libkcal/calformat.h>
00057 #include <libkcal/calendarresources.h>
00058 #include <libkcal/resourcelocal.h>
00059 
00060 #include <qdatetime.h>
00061 #include <qfile.h>
00062 #include <qfileinfo.h>
00063 
00064 #include <stdlib.h>
00065 #include <iostream>
00066 
00067 #include "stdcalendar.h"
00068 #include "konsolekalendar.h"
00069 #include "konsolekalendarepoch.h"
00070 
00071 #include "konsolekalendarvariables.h"
00072 
00073 using namespace KCal;
00074 using namespace std;
00075 
00076 static const char progName[] = "konsolekalendar";
00077 static const char progDisplay[] = "KonsoleKalendar";
00078 static const char progVersion[] = "1.3.5";
00079 static const char progDesc[] = "A command line interface to KDE calendars";
00080 static const char progURL[] = "pim.kde.org/components/konsolekalendar.php";
00081 
00082 
00083 static KCmdLineOptions options[] =
00084 {
00085   { "verbose",
00086     I18N_NOOP( "Print helpful runtime messages" ), 0 },
00087   { "dry-run",
00088     I18N_NOOP( "Print what would have been done, but do not execute" ), 0 },
00089   { "file <calendar-file>",
00090     I18N_NOOP( "Specify which calendar you want to use" ), 0 },
00091 
00092   { ":",
00093     I18N_NOOP( "Incidence types (these options can be combined):" ), 0 },
00094   { "event",
00095     I18N_NOOP( "  Operate for Events only (Default)" ), 0 },
00096   { "todo",
00097     I18N_NOOP( "  Operate for To-dos only [NOT WORKING YET]" ), 0 },
00098   { "journal",
00099     I18N_NOOP( "  Operate for Journals only [NOT WORKING YET]" ), 0 },
00100 
00101   { ":",
00102     I18N_NOOP( "Major operation modes:" ), 0 },
00103   { "view",
00104     I18N_NOOP( "  Print incidences in specified export format" ), 0 },
00105   { "add",
00106     I18N_NOOP( "  Insert an incidence into the calendar" ), 0 },
00107   { "change",
00108     I18N_NOOP( "  Modify an existing incidence" ), 0 },
00109   { "delete",
00110     I18N_NOOP( "  Remove an existing incidence" ), 0 },
00111   { "create",
00112     I18N_NOOP( "  Create new calendar file if one does not exist" ), 0 },
00113   { "import <import-file>",
00114     I18N_NOOP( "  Import this calendar to main calendar" ), 0 },
00115   { ":",
00116     I18N_NOOP( "Operation modifiers:" ), 0 },
00117   { "all",
00118     I18N_NOOP( "  View all calendar entries" ), 0 },
00119   { "next",
00120     I18N_NOOP( "  View next activity in calendar" ), 0 },
00121   { "show-next <days>",
00122     I18N_NOOP( "  From start date show next # days' activities" ), 0 },
00123   { "uid <uid>",
00124     I18N_NOOP( "  Incidence Unique-string identifier" ), 0 },
00125   { "date <start-date>",
00126     I18N_NOOP( "  Start from this day [YYYY-MM-DD]" ), 0 },
00127   { "time <start-time>",
00128     I18N_NOOP( "  Start from this time [HH:MM:SS]" ), 0 },
00129   { "end-date <end-date>",
00130     I18N_NOOP( "  End at this day [YYYY-MM-DD]" ), 0 },
00131   { "end-time <end-time>",
00132     I18N_NOOP( "  End at this time [HH:MM:SS]" ), 0 },
00133   { "epoch-start <epoch-time>",
00134     I18N_NOOP( " Start from this time [secs since epoch]" ), 0 },
00135   { "epoch-end <epoch-time>",
00136     I18N_NOOP( "  End at this time [secs since epoch]" ), 0 },
00137   { "summary <summary>",
00138     I18N_NOOP( "  Add summary to incidence (for add/change modes)" ), 0 },
00139   { "description <description>",
00140     I18N_NOOP( "Add description to incidence (for add/change modes)" ), 0 },
00141   { "location <location>",
00142     I18N_NOOP( "  Add location to incidence (for add/change modes)" ), 0 },
00143 
00144   { ":", I18N_NOOP( "Export options:" ), 0 },
00145   { "export-type <export-type>",
00146     I18N_NOOP( "Export file type (Default: text)" ), 0 },
00147   { "export-file <export-file>",
00148     I18N_NOOP( "Export to file (Default: stdout)" ), 0 },
00149   { "export-list",
00150     I18N_NOOP( "  Print list of export types supported and exit" ), 0 },
00151 
00152   { "",
00153     I18N_NOOP( "Examples:\n"
00154                "  konsolekalendar --view\n"
00155                "  konsolekalendar --add --date 2003-06-04 "
00156                "--time 10:00 --end-time 12:00 \\\n"
00157                "                  --summary \"Doctor Visit\" "
00158                "--description \"Get My Head Examined\"\n"
00159                "  konsolekalendar --delete --uid KOrganizer-1740326.803" ), 0 },
00160 
00161   { "",
00162     I18N_NOOP( "For more information visit the program home page at:\n"
00163                "  http://pim.kde.org/components/konsolekalendar.php" ), 0 },
00164 
00165   KCmdLineLastOption
00166 };
00167 
00168 int main( int argc, char *argv[] )
00169 {
00170   KAboutData aboutData(
00171     progName,                        // internal program name
00172     I18N_NOOP( progDisplay ),        // displayable program name.
00173     progVersion,                     // version string
00174     I18N_NOOP( progDesc ),           // short porgram description
00175     KAboutData::License_GPL,         // license type
00176     "(c) 2002-2005, Tuukka Pasanen and Allen Winter", // copyright statement
00177     0,                               // any free form text
00178     progURL,                         // program home page address
00179     "bugs.kde.org"                   // bug report email address
00180     );
00181 
00182   aboutData.addAuthor(
00183     "Tuukka Pasanen",                // developer's name
00184     I18N_NOOP( "Primary Author" ),   // task or role
00185     "illuusio@mailcity.com",         // email address
00186     0                                // home page or relevant link
00187     );
00188   aboutData.addAuthor(
00189     "Allen Winter",                  // developer's name
00190     I18N_NOOP( "Author" ),           // task or role
00191     "winter@kde.org",                // email address
00192     0                                // home page or relevant link
00193     );
00194 
00195   //TODO: KDE 4.0, add the StdCmdLineArgs option to init()
00196   KCmdLineArgs::init( argc, argv, &aboutData );
00197   KCmdLineArgs::addCmdLineOptions( options ); // Add our own options.
00198 
00199   KApplication app(
00200     false, //do not allowstyles - disable the loading on plugin based styles
00201     false  //GUI is not enabled - disable all GUI stuff
00202     );
00203 
00204   KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
00205 
00206   // Default values for start date/time (today at 07:00)
00207   QDate startdate = QDate::currentDate();
00208   QTime starttime( 7, 0 );
00209 
00210   // Default values for end date/time (today at 17:00)
00211   QDate enddate = QDate::currentDate();
00212   QTime endtime( 17, 0 );
00213 
00214   // Default values for switches
00215   bool view = true;
00216   bool add = false;
00217   bool change = false;
00218   bool del = false;
00219   bool create = false;
00220   bool calendarFile = false;
00221   bool importFile = false;
00222 
00223   QString option;
00224 
00225   KonsoleKalendarVariables variables;
00226   KonsoleKalendarEpoch epochs;
00227 
00228   variables.setFloating( false ); // by default, new events do NOT float
00229 
00230   if ( args->isSet( "verbose" ) ) {
00231     variables.setVerbose( true );
00232   }
00233 
00234   if ( args->isSet( "dry-run" ) ) {
00235     variables.setDryRun( true );
00236   }
00237 
00238   /*
00239    * Switch on export list
00240    */
00241   if ( args->isSet( "export-list" ) ) {
00242     cout << endl;
00243     cout << i18n( "%1 supports these export formats:" ).
00244       arg( progDisplay ).local8Bit()
00245          << endl;
00246     cout << i18n( "  %1 [Default]" ).
00247       arg( "Text" ).local8Bit()
00248          << endl;
00249     cout << i18n( "  %1 (like %2, but more compact)" ).
00250       arg( "Short", "Text" ).local8Bit()
00251          << endl;
00252     cout << i18n( "  %1" ).
00253       arg( "HTML" ).local8Bit()
00254          << endl;
00255     cout << i18n( "  %1 (like %2, but in a month view)" ).
00256       arg( "HTMLmonth", "HTML" ).local8Bit()
00257          << endl;
00258     cout << i18n( "  %1 (Comma-Separated Values)" ).
00259       arg( "CSV" ).local8Bit()
00260          << endl;
00261     cout << endl;
00262     return 0;
00263   }
00264 
00265   /*
00266    * Set incidence type(s)
00267    */
00268   if ( args->isSet( "event" ) ) {
00269     variables.setUseEvents( true );
00270     kdDebug() << "main | parse options | use Events" << endl;
00271   }
00272   if ( args->isSet( "todo" ) ) {
00273     variables.setUseTodos( true );
00274     kdDebug() << "main | parse options | use To-dos" << endl;
00275     cout << i18n( "Sorry, To-dos are not working yet." ).local8Bit()
00276          << endl;
00277     return 1;
00278   }
00279   if ( args->isSet( "journal" ) ) {
00280     variables.setUseJournals( true );
00281     kdDebug() << "main | parse options | use Journals" << endl;
00282     cout << i18n( "Sorry, Journals are not working yet." ).local8Bit()
00283          << endl;
00284     return 1;
00285   }
00286   // Use Events if no incidence type is specified on the command line
00287   if ( !args->isSet( "event" ) &&
00288        !args->isSet( "todo" ) &&
00289        !args->isSet( "journal" ) ) {
00290     variables.setUseEvents( true );
00291     kdDebug() << "main | parse options | use Events (Default)" << endl;
00292   }
00293 
00294   /*
00295    * Switch on exporting
00296    */
00297   variables.setExportType( ExportTypeText );
00298   if ( args->isSet( "export-type" ) ) {
00299     option = args->getOption( "export-type" );
00300 
00301     if ( option.upper() == "HTML" ) {
00302       kdDebug() << "main | export-type | Export to HTML" << endl;
00303       variables.setExportType( ExportTypeHTML );
00304     } else if ( option.upper() == "HTMLMONTH" ) {
00305       kdDebug() << "main | export-type | Export to HTML by Month" << endl;
00306       variables.setExportType( ExportTypeMonthHTML );
00307     } else if ( option.upper() == "CSV" ) {
00308       kdDebug() << "main | export-type | Export to CSV" << endl;
00309       variables.setExportType( ExportTypeCSV );
00310     } else if ( option.upper() == "TEXT" ) {
00311       kdDebug() << "main | export-type | Export to TEXT (default)" << endl;
00312       variables.setExportType( ExportTypeText );
00313     } else if ( option.upper() == "SHORT" ) {
00314       kdDebug() << "main | export-type | Export to TEXT-SHORT" << endl;
00315       variables.setExportType( ExportTypeTextShort );
00316     } else {
00317       cout << i18n( "Invalid Export Type Specified: %1" ).
00318         arg( option ).local8Bit()
00319            << endl;
00320       return 1;
00321     }
00322   }
00323 
00324   /*
00325    * Switch on export file name
00326    */
00327   if ( args->isSet( "export-file" ) ) {
00328     option = args->getOption( "export-file" );
00329 
00330     kdDebug() << "main | parse options | "
00331               << "Export File: "
00332               << "(" << option << ")"
00333               << endl;
00334 
00335     variables.setExportFile( option );
00336   }
00337 
00338   /*
00339    * Switch on View (Print Entries).  This is the default mode of operation.
00340    */
00341   if ( args->isSet( "view" ) ) {
00342     view = true;
00343 
00344     kdDebug() << "main | parse options | "
00345               << "Mode: (Print incidences)"
00346               << endl;
00347   }
00348 
00349   /*
00350    * Switch on Add (Insert Entry)
00351    */
00352   if ( args->isSet( "add" ) ) {
00353     view = false;
00354     add = true;
00355 
00356     kdDebug() << "main | parse options | "
00357               << "Mode: (Add incidence)"
00358               << endl;
00359   }
00360 
00361   /*
00362    * Switch on Change (Modify Entry)
00363    */
00364   if ( args->isSet( "change" ) ) {
00365     view = false;
00366     change = true;
00367 
00368     kdDebug() << "main | parse options | "
00369               << "Mode: (Change incidence)"
00370               << endl;
00371   }
00372 
00373   /*
00374    * Switch on Delete (Remove Entry)
00375    */
00376   if ( args->isSet( "delete" ) ) {
00377     view = false;
00378     del = true;
00379 
00380     kdDebug() << "main | parse options | "
00381               << "Mode: (Delete incidence)"
00382               << endl;
00383   }
00384 
00385   /*
00386    * Switch on Create
00387    */
00388   if ( args->isSet( "create" ) ) {
00389     view = false;
00390     create = true;
00391 
00392     kdDebug() << "main | parse options | "
00393               << "Calendar File: (Create)"
00394               << endl;
00395   }
00396 
00397   /*
00398    * If there is summary attached.
00399    */
00400   if ( args->isSet( "summary" ) ) {
00401     option = args->getOption( "summary" );
00402 
00403     kdDebug() << "main | parse options | "
00404               << "Summary: "
00405               << "(" << option << ")"
00406               << endl;
00407 
00408     variables.setSummary( option );
00409   }
00410 
00411   /*
00412    * If there is description attached.
00413    */
00414   if ( args->isSet( "description" ) ) {
00415     option = args->getOption( "description" );
00416 
00417     kdDebug() << "main | parse options | "
00418               << "Description: "
00419               << "(" << option << ")"
00420               << endl;
00421 
00422     variables.setDescription( option );
00423   }
00424 
00425   /*
00426    * If there is location information
00427    */
00428   if ( args->isSet( "location" ) ) {
00429     option = args->getOption( "location" );
00430 
00431     kdDebug() << "main | parse options | "
00432               << "Location: "
00433               << "(" << option << ")"
00434               << endl;
00435 
00436     variables.setLocation( option );
00437   }
00438 
00439   /*
00440    * Show next happening and exit
00441    */
00442   if ( args->isSet( "next" ) ) {
00443     kdDebug() << "main | parse options | "
00444               << "Show next incidence only"
00445               << endl;
00446 
00447     variables.setNext( true );
00448   }
00449 
00450   /*
00451    * Set incidence unique string identifier
00452    */
00453   if ( args->isSet( "uid" ) ) {
00454     option = args->getOption( "uid" );
00455 
00456     kdDebug() << "main | parse options | "
00457               << "incidence UID: "
00458               << "(" << option << ")"
00459               << endl;
00460 
00461     variables.setUID( option );
00462   }
00463 
00464   /*
00465    * Set starting date for calendar
00466    */
00467   if ( args->isSet( "date" ) ) {
00468     option = args->getOption( "date" );
00469 
00470     kdDebug() << "main | parse options | "
00471               << "Start date before conversion: "
00472               << "(" << option << ")"
00473               << endl;
00474 
00475     startdate = QDate::fromString( option, Qt::ISODate );
00476     if ( !startdate.isValid() ) {
00477       cout << i18n( "Invalid Start Date Specified: %1" ).
00478         arg( option ).local8Bit()
00479            << endl;
00480       return 1;
00481     }
00482     kdDebug() << "main | parse options | "
00483               << "Start date after conversion: "
00484               << "(" << startdate.toString() << ")"
00485               << endl;
00486   }
00487 
00488   /*
00489    * Set starting time
00490    */
00491   if ( args->isSet( "time" ) ) {
00492     option = args->getOption( "time" );
00493 
00494     kdDebug() << "main | parse options | "
00495               << "Start time before conversion : "
00496               << "(" << option << ")"
00497               << endl;
00498 
00499     if ( option.upper() != "FLOAT" ) {
00500       starttime = QTime::fromString( option, Qt::ISODate );
00501       if ( !starttime.isValid() ) {
00502         cout << i18n( "Invalid Start Time Specified: %1" ).
00503           arg( option ).local8Bit()
00504              << endl;
00505         return 1;
00506       }
00507       kdDebug() << "main | parse options | "
00508                 << "Start time after conversion: "
00509                 << "(" << starttime.toString() << ")"
00510                 << endl;
00511     } else {
00512       variables.setFloating( true );
00513       kdDebug() << "main | parse options | "
00514                 << "Floating event time specified"
00515                 << endl;
00516     }
00517   }
00518 
00519   /*
00520    * Set end date for calendar
00521    */
00522   if ( args->isSet( "end-date" ) ) {
00523     option = args->getOption( "end-date" );
00524 
00525     kdDebug() << "main | parse options | "
00526               << "End date before conversion: "
00527               << "(" << option << ")"
00528               << endl;
00529 
00530     enddate = QDate::fromString( option, Qt::ISODate );
00531     if ( !enddate.isValid() ) {
00532       cout << i18n( "Invalid End Date Specified: %1" ).
00533         arg( option ).local8Bit()
00534            << endl;
00535       return 1;
00536     }
00537     kdDebug() << "main | parse options | "
00538               << "End date after conversion: "
00539               << "(" << enddate.toString() << ")"
00540               << endl;
00541   }
00542 
00543   /*
00544    * Show next # days and exit
00545    */
00546   if ( args->isSet( "show-next" ) ) {
00547     bool ok;
00548 
00549     option = args->getOption( "show-next" );
00550     kdDebug() << "main | parse options | "
00551               << "Show " << option << " days ahead"
00552               << endl;
00553     variables.setDaysCount( option.toInt( &ok, 10 ) );
00554 
00555     if ( !ok ) {
00556       cout << i18n( "Invalid Date Count Specified: %1" ).
00557         arg( option ).local8Bit()
00558            << endl;
00559       return 1;
00560     }
00561 
00562     enddate = startdate;
00563     enddate = enddate.addDays( variables.getDaysCount() );
00564     kdDebug() << "main | parse options | "
00565               << "End date after conversion: "
00566               << "(" << enddate.toString() << ")"
00567               << endl;
00568   }
00569 
00570   /*
00571    * Set ending time
00572    */
00573   if ( args->isSet( "end-time" ) ) {
00574     option = args->getOption( "end-time" );
00575 
00576     kdDebug() << "main | parse options | "
00577               << "End time before conversion: "
00578               << "(" << option << ")"
00579               << endl;
00580 
00581     if ( option.upper() != "FLOAT" ) {
00582       endtime = QTime::fromString( option, Qt::ISODate );
00583       if ( !endtime.isValid() ) {
00584         cout << i18n( "Invalid End Time Specified: %1" ).
00585           arg( option ).local8Bit()
00586              << endl;
00587         return 1;
00588       }
00589 
00590       kdDebug() << "main | parse options | "
00591                 << "End time after conversion: "
00592                 << "(" << endtime.toString() << ")"
00593                 << endl;
00594     } else {
00595       variables.setFloating( true );
00596       kdDebug() << "main | parse options | "
00597                 << "Floating event time specified"
00598                 << endl;
00599     }
00600   }
00601 
00602   /*
00603    * Set start date/time from epoch
00604    */
00605   time_t epochstart = 0;
00606   if ( args->isSet( "epoch-start" ) ) {
00607     option = args->getOption( "epoch-start" );
00608 
00609     kdDebug() << "main | parse options | "
00610               << "Epoch start: "
00611               << "(" << option << ")"
00612               << endl;
00613 
00614     epochstart = ( time_t ) option.toULong( 0, 10 );
00615   }
00616 
00617   /*
00618    * Set end date/time from epoch
00619    */
00620   time_t epochend = 0;
00621   if ( args->isSet( "epoch-end" ) ) {
00622     option = args->getOption( "epoch-end" );
00623 
00624     kdDebug() << "main | parse options | "
00625               << "Epoch end: "
00626               << "(" << option << ")"
00627               << endl;
00628 
00629     epochend = ( time_t ) option.toULong( 0, 10 );
00630   }
00631 
00632   if ( args->isSet( "all" ) ) {
00633     variables.setAll( true );
00634   } else {
00635     variables.setAll( false );
00636   }
00637 
00638   if ( args->isSet( "import" ) ) {
00639     view = false;
00640     importFile = true;
00641     option = args->getOption( "import" );
00642     variables.setImportFile( option );
00643 
00644     kdDebug() << "main | parse options | "
00645               << "importing file from: "
00646               << "(" << option << ")"
00647               << endl;
00648   }
00649 
00650   KonsoleKalendar *konsolekalendar = new KonsoleKalendar( &variables );
00651 
00652   if ( args->isSet( "file" ) ) {
00653     calendarFile = true;
00654     option = args->getOption( "file" );
00655     variables.setCalendarFile( option );
00656 
00657     /*
00658      * All modes need to know if the calendar file exists
00659      * This must be done before we get to opening biz
00660      */
00661     bool exists, remote;
00662     KURL url = KURL::fromPathOrURL( variables.getCalendarFile() );
00663     if ( url.isLocalFile() ) {
00664       variables.setCalendarFile( url.path() );
00665       exists = QFile::exists( variables.getCalendarFile() );
00666       remote = false;
00667     } else if ( url.protocol().isEmpty() ) {
00668       QFileInfo info( variables.getCalendarFile() );
00669       variables.setCalendarFile( info.absFilePath() );
00670       exists = QFile::exists( variables.getCalendarFile() );
00671       remote = false;
00672     } else {
00673       exists = true; // really have no idea if the remote file exists
00674       remote = true;
00675     }
00676 
00677     if ( create ) {
00678 
00679       kdDebug() << "main | createcalendar | "
00680                 << "check if calendar file already exists"
00681                 << endl;
00682 
00683       if ( remote ) {
00684         cout << i18n( "Attempting to create a remote file %1" ).
00685           arg( variables.getCalendarFile() ).local8Bit() << endl;
00686         return 1;
00687       } else {
00688         if ( exists ) {
00689           cout << i18n( "Calendar %1 already exists" ).
00690             arg( variables.getCalendarFile() ).local8Bit()
00691                << endl;
00692           return 1;
00693         }
00694       }
00695 
00696       if ( konsolekalendar->createCalendar() ) {
00697         cout << i18n( "Calendar %1 successfully created" ).
00698           arg( variables.getCalendarFile() ).local8Bit()
00699              << endl;
00700         return 0;
00701       } else {
00702         cout << i18n( "Unable to create calendar: %1" ).
00703           arg( variables.getCalendarFile() ).local8Bit()
00704              << endl;
00705         return 1;
00706       }
00707     }
00708 
00709     if ( !exists ) {
00710       cout << i18n( "Calendar file not found %1" ).
00711         arg( variables.getCalendarFile() ).local8Bit()
00712            << endl;
00713       cout << i18n( "Try --create to create new calendar file" ).local8Bit()
00714            << endl;
00715       return 1;
00716     }
00717   }
00718 
00719   CalendarResources *calendarResource = NULL;
00720   /*
00721    * Should we use local calendar or resource?
00722    */
00723   if ( args->isSet( "file" ) ) {
00724     calendarResource = new StdCalendar( variables.getCalendarFile(),
00725                                         i18n( "Active Calendar" ) );
00726   } else {
00727     // TODO: when certain resources (kolab) don't try to gain access to
00728     // an X server, or dcopserver, then put back the following line which
00729     // supports all resources, not just the standard resource.
00730     // calendarResource = new StdCalendar();
00731     calendarResource = new StdCalendar( locateLocal( "data",
00732                                                      "korganizer/std.ics" ),
00733                                         i18n( "Default Calendar" ) );
00734   }
00735   if ( !args->isSet( "import" ) ) {
00736     variables.setCalendar( calendarResource );
00737     calendarResource->load();
00738   }
00739 
00740   /***************************************************************************
00741    * Glorious date/time checking and setting code                            *
00742    ***************************************************************************/
00743   QDateTime startdatetime, enddatetime;
00744 
00745   // Handle case with either date or end-date unspecified
00746   if ( !args->isSet( "end-date" ) && !args->isSet( "show-next" ) &&
00747        args->isSet( "date" ) ) {
00748     enddate = startdate;
00749     kdDebug() << "main | datetimestamp | "
00750               << "setting enddate to startdate"
00751               << endl;
00752   } else if ( args->isSet( "end-date" ) && !args->isSet( "date" ) ) {
00753     startdate = enddate;
00754     kdDebug() << "main | datetimestamp | "
00755               << "setting startdate to enddate"
00756               << endl;
00757   }
00758 
00759   // NOTE: If neither date nor end-date specified, then event will be today.
00760 
00761   // Case:
00762   //   End time (or epoch) unspecified, and start time (or epoch) IS specified.
00763   //   In this case, set the ending to 1 hour after starting.
00764   if ( !args->isSet( "end-time" ) && !args->isSet( "epoch-end" ) ) {
00765     if ( args->isSet( "time" ) ) {
00766       endtime = starttime.addSecs( 60 * 60 );  // end is 1 hour after start
00767       kdDebug() << "main | datetimestamp | "
00768                 << "setting endtime 1 hour after starttime"
00769                 << endl;
00770     } else if ( args->isSet( "epoch-start" ) ) {
00771       startdatetime = epochs.epoch2QDateTime( epochstart );
00772       enddatetime = startdatetime.addSecs( 60 * 60 );
00773       kdDebug() << "main | datetimestamp | "
00774                 << "setting endtime 1 hour after epochstart"
00775                 << endl;
00776     }
00777   }
00778 
00779   // Case:
00780   //   Time (or epoch) unspecified, and end-time (or epoch) IS specified.
00781   //   In this case, set the starting to 1 hour before ending.
00782   if ( !args->isSet( "time" ) && !args->isSet( "epoch-start" ) ) {
00783     if ( args->isSet( "end-time" ) ) {
00784       starttime = endtime.addSecs( -60 * 60 );  // start is 1 hour before end
00785       kdDebug() << "main | datetimestamp | "
00786                 << "setting starttime 1 hour before endtime"
00787                 << endl;
00788     } else if ( args->isSet( "epoch-end" ) ) {
00789       enddatetime = epochs.epoch2QDateTime( epochend );
00790       startdatetime = enddatetime.addSecs( -60 * 60 );
00791       kdDebug() << "main | datetimestamp | "
00792                 << "setting starttime 1 before after epochend"
00793                 << endl;
00794     }
00795   }
00796 
00797   // Case:
00798   //   Time (or epoch) unspecified, and end-time (or epoch) unspecified.
00799   if ( !args->isSet( "time" )     && !args->isSet( "epoch-start" ) &&
00800        !args->isSet( "end-time" ) && !args->isSet( "epoch-end" ) ) {
00801     // set default start date/time
00802     startdatetime = QDateTime::QDateTime( startdate, starttime );
00803     kdDebug() << "main | datetimestamp | "
00804               << "setting startdatetime from "
00805               << "default startdate (today) and starttime"
00806               << endl;
00807     // set default end date/time
00808     enddatetime = QDateTime::QDateTime( enddate, endtime );
00809     kdDebug() << "main | datetimestamp | "
00810               << "setting enddatetime from "
00811               << "default enddate (today) and endtime"
00812               << endl;
00813   }
00814 
00815   // Set startdatetime, enddatetime if still necessary
00816   if ( startdatetime.isNull() ) {
00817     startdatetime = QDateTime::QDateTime( startdate, starttime );
00818     kdDebug() << "main | datetimestamp | "
00819               << "setting startdatetime from startdate and starttime"
00820               << endl;
00821   }
00822   if ( enddatetime.isNull() ) {
00823     enddatetime = QDateTime::QDateTime( enddate, endtime );
00824     kdDebug() << "main | datetimestamp | "
00825               << "setting enddatetime from enddate and endtime"
00826               << endl;
00827   }
00828 
00829   // Float check for add mode:
00830   //   Events float if time AND end-time AND epoch times are UNspecified
00831   if ( add ) {
00832     if ( !args->isSet( "time" )        && !args->isSet( "end-time" ) &&
00833          !args->isSet( "epoch-start" ) && !args->isSet( "epoch-end" ) ) {
00834       variables.setFloating( true );
00835       kdDebug() << "main | floatingcheck | "
00836                 << "turn-on floating event"
00837                 << endl;
00838     }
00839   }
00840 
00841   // Finally! Set the start/end date times
00842   if ( !change ) {
00843     variables.setStartDateTime( startdatetime );
00844     variables.setEndDateTime( enddatetime );
00845   } else {
00846     // Do NOT set start/end datetimes in change mode,
00847     //   unless they were specified on commandline
00848     if ( args->isSet( "time" )     || args->isSet( "epoch-start" ) ||
00849          args->isSet( "end-time" ) || args->isSet( "epoch-end" ) ) {
00850       variables.setStartDateTime( startdatetime );
00851       variables.setEndDateTime( enddatetime );
00852     }
00853   }
00854 
00855   // Some more debug prints
00856   kdDebug() << "main | datetimestamp | StartDate="
00857             << startdatetime.toString( Qt::TextDate )
00858             << endl;
00859   kdDebug() << "main | datetimestamp | EndDate="
00860             << enddatetime.toString( Qt::TextDate )
00861             << endl;
00862 
00863   /***************************************************************************
00864    * Sanity checks                                                           *
00865    ***************************************************************************/
00866 
00867   // Cannot combine modes
00868   if ( create + view + add + change + del > 1 ) {
00869     cout << i18n(
00870       "Only 1 operation mode "
00871       "(view, add, change, delete, create) "
00872       "permitted at any one time"
00873       ).local8Bit() << endl;
00874     return 1;
00875   }
00876 
00877   // Cannot have a ending before starting
00878   if ( startdatetime > enddatetime ) {
00879     cout << i18n(
00880       "Ending Date/Time occurs before the Starting Date/Time"
00881       ).local8Bit() << endl;
00882     return 1;
00883   }
00884 
00885   /***************************************************************************
00886    * And away we go with the real work...                                    *
00887    ***************************************************************************/
00888 
00889   args->clear(); // Free up some memory.
00890 
00891   /*
00892    * Set our application name for use in unique IDs and error messages,
00893    * and product ID for incidence PRODID property
00894    */
00895   QString prodId = "-//K Desktop Environment//NONSGML %1 %2//EN";
00896   CalFormat::setApplication( progDisplay,
00897                              prodId.arg( progDisplay ).arg( progVersion ) );
00898 
00899   if ( importFile ) {
00900     if ( konsolekalendar->importCalendar() ) {
00901       cout << i18n( "Calendar %1 successfully imported" ).
00902         arg( variables.getImportFile() ).local8Bit()
00903            << endl;
00904       return 0;
00905     } else {
00906       cout << i18n( "Unable to import calendar: %1" ).
00907         arg( variables.getImportFile() ).local8Bit()
00908            << endl;
00909       return 1;
00910     }
00911   }
00912 
00913   if ( add ) {
00914     if ( !konsolekalendar->isEvent( startdatetime, enddatetime,
00915                                      variables.getSummary() ) ) {
00916       kdDebug() << "main | modework | "
00917                 << "calling addEvent()"
00918                 << endl;
00919       konsolekalendar->addEvent();
00920     } else {
00921       cout << i18n(
00922         "Attempting to insert an event that already exists"
00923         ).local8Bit() << endl;
00924       return 1;
00925     }
00926   }
00927 
00928   if ( change ) {
00929     kdDebug() << "main | modework | "
00930               << "calling changeEvent()"
00931               << endl;
00932     if ( !variables.isUID() ) {
00933       cout << i18n( "Missing event UID: "
00934                     "use --uid command line option" ).local8Bit()
00935            << endl;
00936       return 1;
00937     }
00938     if ( konsolekalendar->changeEvent() != true ) {
00939       cout << i18n( "No such event UID: change event failed" ).local8Bit()
00940            << endl;
00941       return 1;
00942     }
00943     kdDebug() << "main | modework | "
00944               << "successful changeEvent()"
00945               << endl;
00946   }
00947 
00948   if ( del ) {
00949     kdDebug() << "main | modework | "
00950               << "calling deleteEvent()"
00951               << endl;
00952     if ( !variables.isUID() ) {
00953       cout << i18n( "Missing event UID: "
00954                     "use --uid command line option" ).local8Bit()
00955            << endl;
00956       return 1;
00957     }
00958     if ( konsolekalendar->deleteEvent() != true ) {
00959       cout << i18n( "No such event UID: delete event failed").local8Bit()
00960            << endl;
00961       return 1;
00962     }
00963     kdDebug() << "main | modework | "
00964               << "successful deleteEvent()"
00965               << endl;
00966   }
00967 
00968   if ( view ) {
00969     kdDebug() << "main | modework | "
00970               << "calling showInstance() to view events"
00971               << endl;
00972     if ( !konsolekalendar->showInstance() ) {
00973       cout << i18n( "Cannot open specified export file: %1" ).
00974         arg( variables.getExportFile() ).local8Bit()
00975            << endl;
00976       return 1;
00977     }
00978   }
00979 
00980   delete konsolekalendar;
00981 
00982   calendarResource->close();
00983   delete calendarResource;
00984 
00985   kdDebug() << "main | exiting"
00986             << endl;
00987 
00988   return 0;
00989 }