konsolekalendar

main.cpp
Go to the documentation of this file.
1 /*******************************************************************************
2  * main.cpp *
3  * *
4  * KonsoleKalendar is a command line interface to KDE calendars *
5  * Copyright (C) 2002-2004 Tuukka Pasanen <illuusio@mailcity.com> *
6  * Copyright (C) 2003-2005 Allen Winter <winter@kde.org> *
7  * *
8  * This program is free software; you can redistribute it and/or modify *
9  * it under the terms of the GNU General Public License as published by *
10  * the Free Software Foundation; either version 2 of the License, or *
11  * (at your option) any later version. *
12  * *
13  * This program is distributed in the hope that it will be useful, *
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16  * GNU General Public License for more details. *
17  * *
18  * You should have received a copy of the GNU General Public License *
19  * along with this program; if not, write to the Free Software *
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
21  * *
22  * As a special exception, permission is given to link this program *
23  * with any edition of TQt, and distribute the resulting executable, *
24  * without including the source code for TQt in the source distribution. *
25  * *
26  ******************************************************************************/
33 #ifdef HAVE_CONFIG_H
34 #include "config.h"
35 #endif
36 
37 #if TIME_WITH_SYS_TIME
38 # include <sys/time.h>
39 # include <time.h>
40 #else
41 # if HAVE_SYS_TIME_H
42 # include <sys/time.h>
43 # else
44 # include <time.h>
45 # endif
46 #endif
47 
48 #include <kcmdlineargs.h>
49 #include <kaboutdata.h>
50 #include <klocale.h>
51 #include <kglobal.h>
52 #include <kconfig.h>
53 #include <kstandarddirs.h>
54 #include <kdebug.h>
55 
56 #include <libkcal/calformat.h>
57 #include <libkcal/calendarresources.h>
58 #include <libkcal/resourcelocal.h>
59 
60 #include <tqdatetime.h>
61 #include <tqfile.h>
62 #include <tqfileinfo.h>
63 
64 #include <stdlib.h>
65 #include <iostream>
66 
67 #include "stdcalendar.h"
68 #include "konsolekalendar.h"
69 #include "konsolekalendarepoch.h"
70 
72 
73 using namespace KCal;
74 using namespace std;
75 
76 static const char progName[] = "konsolekalendar";
77 static const char progDisplay[] = "KonsoleKalendar";
78 static const char progVersion[] = "1.3.5";
79 static const char progDesc[] = "A command line interface to KDE calendars";
80 static const char progURL[] = "pim.kde.org/components/konsolekalendar.php";
81 
82 
83 static KCmdLineOptions options[] =
84 {
85  { "verbose",
86  I18N_NOOP( "Print helpful runtime messages" ), 0 },
87  { "dry-run",
88  I18N_NOOP( "Print what would have been done, but do not execute" ), 0 },
89  { "file <calendar-file>",
90  I18N_NOOP( "Specify which calendar you want to use" ), 0 },
91 
92  { ":",
93  I18N_NOOP( "Incidence types (these options can be combined):" ), 0 },
94  { "event",
95  I18N_NOOP( " Operate for Events only (Default)" ), 0 },
96  { "todo",
97  I18N_NOOP( " Operate for To-dos only [NOT WORKING YET]" ), 0 },
98  { "journal",
99  I18N_NOOP( " Operate for Journals only [NOT WORKING YET]" ), 0 },
100 
101  { ":",
102  I18N_NOOP( "Major operation modes:" ), 0 },
103  { "view",
104  I18N_NOOP( " Print incidences in specified export format" ), 0 },
105  { "add",
106  I18N_NOOP( " Insert an incidence into the calendar" ), 0 },
107  { "change",
108  I18N_NOOP( " Modify an existing incidence" ), 0 },
109  { "delete",
110  I18N_NOOP( " Remove an existing incidence" ), 0 },
111  { "create",
112  I18N_NOOP( " Create new calendar file if one does not exist" ), 0 },
113  { "import <import-file>",
114  I18N_NOOP( " Import this calendar to main calendar" ), 0 },
115  { ":",
116  I18N_NOOP( "Operation modifiers:" ), 0 },
117  { "all",
118  I18N_NOOP( " View all calendar entries" ), 0 },
119  { "next",
120  I18N_NOOP( " View next activity in calendar" ), 0 },
121  { "show-next <days>",
122  I18N_NOOP( " From start date show next # days' activities" ), 0 },
123  { "uid <uid>",
124  I18N_NOOP( " Incidence Unique-string identifier" ), 0 },
125  { "date <start-date>",
126  I18N_NOOP( " Start from this day [YYYY-MM-DD]" ), 0 },
127  { "time <start-time>",
128  I18N_NOOP( " Start from this time [HH:MM:SS]" ), 0 },
129  { "end-date <end-date>",
130  I18N_NOOP( " End at this day [YYYY-MM-DD]" ), 0 },
131  { "end-time <end-time>",
132  I18N_NOOP( " End at this time [HH:MM:SS]" ), 0 },
133  { "epoch-start <epoch-time>",
134  I18N_NOOP( " Start from this time [secs since epoch]" ), 0 },
135  { "epoch-end <epoch-time>",
136  I18N_NOOP( " End at this time [secs since epoch]" ), 0 },
137  { "summary <summary>",
138  I18N_NOOP( " Add summary to incidence (for add/change modes)" ), 0 },
139  { "description <description>",
140  I18N_NOOP( "Add description to incidence (for add/change modes)" ), 0 },
141  { "location <location>",
142  I18N_NOOP( " Add location to incidence (for add/change modes)" ), 0 },
143 
144  { ":", I18N_NOOP( "Export options:" ), 0 },
145  { "export-type <export-type>",
146  I18N_NOOP( "Export file type (Default: text)" ), 0 },
147  { "export-file <export-file>",
148  I18N_NOOP( "Export to file (Default: stdout)" ), 0 },
149  { "export-list",
150  I18N_NOOP( " Print list of export types supported and exit" ), 0 },
151 
152  { "",
153  I18N_NOOP( "Examples:\n"
154  " konsolekalendar --view\n"
155  " konsolekalendar --add --date 2003-06-04 "
156  "--time 10:00 --end-time 12:00 \\\n"
157  " --summary \"Doctor Visit\" "
158  "--description \"Get My Head Examined\"\n"
159  " konsolekalendar --delete --uid KOrganizer-1740326.803" ), 0 },
160 
161  { "",
162  I18N_NOOP( "For more information visit the program home page at:\n"
163  " http://pim.kde.org/components/konsolekalendar.php" ), 0 },
164 
165  KCmdLineLastOption
166 };
167 
168 int main( int argc, char *argv[] )
169 {
170  KAboutData aboutData(
171  progName, // internal program name
172  I18N_NOOP( progDisplay ), // displayable program name.
173  progVersion, // version string
174  I18N_NOOP( progDesc ), // short porgram description
175  KAboutData::License_GPL, // license type
176  "(c) 2002-2005, Tuukka Pasanen and Allen Winter", // copyright statement
177  0, // any free form text
178  progURL, // program home page address
179  "bugs.kde.org" // bug report email address
180  );
181 
182  aboutData.addAuthor(
183  "Tuukka Pasanen", // developer's name
184  I18N_NOOP( "Primary Author" ), // task or role
185  "illuusio@mailcity.com", // email address
186  0 // home page or relevant link
187  );
188  aboutData.addAuthor(
189  "Allen Winter", // developer's name
190  I18N_NOOP( "Author" ), // task or role
191  "winter@kde.org", // email address
192  0 // home page or relevant link
193  );
194 
195  //TODO: KDE 4.0, add the StdCmdLineArgs option to init()
196  KCmdLineArgs::init( argc, argv, &aboutData );
197  KCmdLineArgs::addCmdLineOptions( options ); // Add our own options.
198 
199  KApplication app(
200  false, //do not allowstyles - disable the loading on plugin based styles
201  false //GUI is not enabled - disable all GUI stuff
202  );
203 
204  KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
205 
206  // Default values for start date/time (today at 07:00)
207  TQDate startdate = TQDate::currentDate();
208  TQTime starttime( 7, 0 );
209 
210  // Default values for end date/time (today at 17:00)
211  TQDate enddate = TQDate::currentDate();
212  TQTime endtime( 17, 0 );
213 
214  // Default values for switches
215  bool view = true;
216  bool add = false;
217  bool change = false;
218  bool del = false;
219  bool create = false;
220  bool calendarFile = false;
221  bool importFile = false;
222 
223  TQString option;
224 
225  KonsoleKalendarVariables variables;
226  KonsoleKalendarEpoch epochs;
227 
228  variables.setFloating( false ); // by default, new events do NOT float
229 
230  if ( args->isSet( "verbose" ) ) {
231  variables.setVerbose( true );
232  }
233 
234  if ( args->isSet( "dry-run" ) ) {
235  variables.setDryRun( true );
236  }
237 
238  /*
239  * Switch on export list
240  */
241  if ( args->isSet( "export-list" ) ) {
242  cout << endl;
243  cout << i18n( "%1 supports these export formats:" ).
244  arg( progDisplay ).local8Bit().data()
245  << endl;
246  cout << i18n( " %1 [Default]" ).
247  arg( "Text" ).local8Bit().data()
248  << endl;
249  cout << i18n( " %1 (like %2, but more compact)" ).
250  arg( "Short", "Text" ).local8Bit().data()
251  << endl;
252  cout << i18n( " %1" ).
253  arg( "HTML" ).local8Bit().data()
254  << endl;
255  cout << i18n( " %1 (like %2, but in a month view)" ).
256  arg( "HTMLmonth", "HTML" ).local8Bit().data()
257  << endl;
258  cout << i18n( " %1 (Comma-Separated Values)" ).
259  arg( "CSV" ).local8Bit().data()
260  << endl;
261  cout << endl;
262  return 0;
263  }
264 
265  /*
266  * Set incidence type(s)
267  */
268  if ( args->isSet( "event" ) ) {
269  variables.setUseEvents( true );
270  kdDebug() << "main | parse options | use Events" << endl;
271  }
272  if ( args->isSet( "todo" ) ) {
273  variables.setUseTodos( true );
274  kdDebug() << "main | parse options | use To-dos" << endl;
275  cout << i18n( "Sorry, To-dos are not working yet." ).local8Bit().data()
276  << endl;
277  return 1;
278  }
279  if ( args->isSet( "journal" ) ) {
280  variables.setUseJournals( true );
281  kdDebug() << "main | parse options | use Journals" << endl;
282  cout << i18n( "Sorry, Journals are not working yet." ).local8Bit().data()
283  << endl;
284  return 1;
285  }
286  // Use Events if no incidence type is specified on the command line
287  if ( !args->isSet( "event" ) &&
288  !args->isSet( "todo" ) &&
289  !args->isSet( "journal" ) ) {
290  variables.setUseEvents( true );
291  kdDebug() << "main | parse options | use Events (Default)" << endl;
292  }
293 
294  /*
295  * Switch on exporting
296  */
297  variables.setExportType( ExportTypeText );
298  if ( args->isSet( "export-type" ) ) {
299  option = args->getOption( "export-type" );
300 
301  if ( option.upper() == "HTML" ) {
302  kdDebug() << "main | export-type | Export to HTML" << endl;
303  variables.setExportType( ExportTypeHTML );
304  } else if ( option.upper() == "HTMLMONTH" ) {
305  kdDebug() << "main | export-type | Export to HTML by Month" << endl;
306  variables.setExportType( ExportTypeMonthHTML );
307  } else if ( option.upper() == "CSV" ) {
308  kdDebug() << "main | export-type | Export to CSV" << endl;
309  variables.setExportType( ExportTypeCSV );
310  } else if ( option.upper() == "TEXT" ) {
311  kdDebug() << "main | export-type | Export to TEXT (default)" << endl;
312  variables.setExportType( ExportTypeText );
313  } else if ( option.upper() == "SHORT" ) {
314  kdDebug() << "main | export-type | Export to TEXT-SHORT" << endl;
315  variables.setExportType( ExportTypeTextShort );
316  } else {
317  cout << i18n( "Invalid Export Type Specified: %1" ).
318  arg( option ).local8Bit().data()
319  << endl;
320  return 1;
321  }
322  }
323 
324  /*
325  * Switch on export file name
326  */
327  if ( args->isSet( "export-file" ) ) {
328  option = args->getOption( "export-file" );
329 
330  kdDebug() << "main | parse options | "
331  << "Export File: "
332  << "(" << option << ")"
333  << endl;
334 
335  variables.setExportFile( option );
336  }
337 
338  /*
339  * Switch on View (Print Entries). This is the default mode of operation.
340  */
341  if ( args->isSet( "view" ) ) {
342  view = true;
343 
344  kdDebug() << "main | parse options | "
345  << "Mode: (Print incidences)"
346  << endl;
347  }
348 
349  /*
350  * Switch on Add (Insert Entry)
351  */
352  if ( args->isSet( "add" ) ) {
353  view = false;
354  add = true;
355 
356  kdDebug() << "main | parse options | "
357  << "Mode: (Add incidence)"
358  << endl;
359  }
360 
361  /*
362  * Switch on Change (Modify Entry)
363  */
364  if ( args->isSet( "change" ) ) {
365  view = false;
366  change = true;
367 
368  kdDebug() << "main | parse options | "
369  << "Mode: (Change incidence)"
370  << endl;
371  }
372 
373  /*
374  * Switch on Delete (Remove Entry)
375  */
376  if ( args->isSet( "delete" ) ) {
377  view = false;
378  del = true;
379 
380  kdDebug() << "main | parse options | "
381  << "Mode: (Delete incidence)"
382  << endl;
383  }
384 
385  /*
386  * Switch on Create
387  */
388  if ( args->isSet( "create" ) ) {
389  view = false;
390  create = true;
391 
392  kdDebug() << "main | parse options | "
393  << "Calendar File: (Create)"
394  << endl;
395  }
396 
397  /*
398  * If there is summary attached.
399  */
400  if ( args->isSet( "summary" ) ) {
401  option = args->getOption( "summary" );
402 
403  kdDebug() << "main | parse options | "
404  << "Summary: "
405  << "(" << option << ")"
406  << endl;
407 
408  variables.setSummary( option );
409  }
410 
411  /*
412  * If there is description attached.
413  */
414  if ( args->isSet( "description" ) ) {
415  option = args->getOption( "description" );
416 
417  kdDebug() << "main | parse options | "
418  << "Description: "
419  << "(" << option << ")"
420  << endl;
421 
422  variables.setDescription( option );
423  }
424 
425  /*
426  * If there is location information
427  */
428  if ( args->isSet( "location" ) ) {
429  option = args->getOption( "location" );
430 
431  kdDebug() << "main | parse options | "
432  << "Location: "
433  << "(" << option << ")"
434  << endl;
435 
436  variables.setLocation( option );
437  }
438 
439  /*
440  * Show next happening and exit
441  */
442  if ( args->isSet( "next" ) ) {
443  kdDebug() << "main | parse options | "
444  << "Show next incidence only"
445  << endl;
446 
447  variables.setNext( true );
448  }
449 
450  /*
451  * Set incidence unique string identifier
452  */
453  if ( args->isSet( "uid" ) ) {
454  option = args->getOption( "uid" );
455 
456  kdDebug() << "main | parse options | "
457  << "incidence UID: "
458  << "(" << option << ")"
459  << endl;
460 
461  variables.setUID( option );
462  }
463 
464  /*
465  * Set starting date for calendar
466  */
467  if ( args->isSet( "date" ) ) {
468  option = args->getOption( "date" );
469 
470  kdDebug() << "main | parse options | "
471  << "Start date before conversion: "
472  << "(" << option << ")"
473  << endl;
474 
475  startdate = TQDate::fromString( option, Qt::ISODate );
476  if ( !startdate.isValid() ) {
477  cout << i18n( "Invalid Start Date Specified: %1" ).
478  arg( option ).local8Bit().data()
479  << endl;
480  return 1;
481  }
482  kdDebug() << "main | parse options | "
483  << "Start date after conversion: "
484  << "(" << TQString(startdate.toString()) << ")"
485  << endl;
486  }
487 
488  /*
489  * Set starting time
490  */
491  if ( args->isSet( "time" ) ) {
492  option = args->getOption( "time" );
493 
494  kdDebug() << "main | parse options | "
495  << "Start time before conversion : "
496  << "(" << option << ")"
497  << endl;
498 
499  if ( option.upper() != "FLOAT" ) {
500  starttime = TQTime::fromString( option, Qt::ISODate );
501  if ( !starttime.isValid() ) {
502  cout << i18n( "Invalid Start Time Specified: %1" ).
503  arg( option ).local8Bit().data()
504  << endl;
505  return 1;
506  }
507  kdDebug() << "main | parse options | "
508  << "Start time after conversion: "
509  << "(" << TQString(starttime.toString()) << ")"
510  << endl;
511  } else {
512  variables.setFloating( true );
513  kdDebug() << "main | parse options | "
514  << "Floating event time specified"
515  << endl;
516  }
517  }
518 
519  /*
520  * Set end date for calendar
521  */
522  if ( args->isSet( "end-date" ) ) {
523  option = args->getOption( "end-date" );
524 
525  kdDebug() << "main | parse options | "
526  << "End date before conversion: "
527  << "(" << option << ")"
528  << endl;
529 
530  enddate = TQDate::fromString( option, Qt::ISODate );
531  if ( !enddate.isValid() ) {
532  cout << i18n( "Invalid End Date Specified: %1" ).
533  arg( option ).local8Bit().data()
534  << endl;
535  return 1;
536  }
537  kdDebug() << "main | parse options | "
538  << "End date after conversion: "
539  << "(" << TQString(enddate.toString()) << ")"
540  << endl;
541  }
542 
543  /*
544  * Show next # days and exit
545  */
546  if ( args->isSet( "show-next" ) ) {
547  bool ok;
548 
549  option = args->getOption( "show-next" );
550  kdDebug() << "main | parse options | "
551  << "Show " << option << " days ahead"
552  << endl;
553  variables.setDaysCount( option.toInt( &ok, 10 ) );
554 
555  if ( !ok ) {
556  cout << i18n( "Invalid Date Count Specified: %1" ).
557  arg( option ).local8Bit().data()
558  << endl;
559  return 1;
560  }
561 
562  enddate = startdate;
563  enddate = enddate.addDays( variables.getDaysCount() );
564  kdDebug() << "main | parse options | "
565  << "End date after conversion: "
566  << "(" << TQString(enddate.toString()) << ")"
567  << endl;
568  }
569 
570  /*
571  * Set ending time
572  */
573  if ( args->isSet( "end-time" ) ) {
574  option = args->getOption( "end-time" );
575 
576  kdDebug() << "main | parse options | "
577  << "End time before conversion: "
578  << "(" << option << ")"
579  << endl;
580 
581  if ( option.upper() != "FLOAT" ) {
582  endtime = TQTime::fromString( option, Qt::ISODate );
583  if ( !endtime.isValid() ) {
584  cout << i18n( "Invalid End Time Specified: %1" ).
585  arg( option ).local8Bit().data()
586  << endl;
587  return 1;
588  }
589 
590  kdDebug() << "main | parse options | "
591  << "End time after conversion: "
592  << "(" << TQString(endtime.toString()) << ")"
593  << endl;
594  } else {
595  variables.setFloating( true );
596  kdDebug() << "main | parse options | "
597  << "Floating event time specified"
598  << endl;
599  }
600  }
601 
602  /*
603  * Set start date/time from epoch
604  */
605  time_t epochstart = 0;
606  if ( args->isSet( "epoch-start" ) ) {
607  option = args->getOption( "epoch-start" );
608 
609  kdDebug() << "main | parse options | "
610  << "Epoch start: "
611  << "(" << option << ")"
612  << endl;
613 
614  epochstart = ( time_t ) option.toULong( 0, 10 );
615  }
616 
617  /*
618  * Set end date/time from epoch
619  */
620  time_t epochend = 0;
621  if ( args->isSet( "epoch-end" ) ) {
622  option = args->getOption( "epoch-end" );
623 
624  kdDebug() << "main | parse options | "
625  << "Epoch end: "
626  << "(" << option << ")"
627  << endl;
628 
629  epochend = ( time_t ) option.toULong( 0, 10 );
630  }
631 
632  if ( args->isSet( "all" ) ) {
633  variables.setAll( true );
634  } else {
635  variables.setAll( false );
636  }
637 
638  if ( args->isSet( "import" ) ) {
639  view = false;
640  importFile = true;
641  option = args->getOption( "import" );
642  variables.setImportFile( option );
643 
644  kdDebug() << "main | parse options | "
645  << "importing file from: "
646  << "(" << option << ")"
647  << endl;
648  }
649 
650  KonsoleKalendar *konsolekalendar = new KonsoleKalendar( &variables );
651 
652  if ( args->isSet( "file" ) ) {
653  calendarFile = true;
654  option = args->getOption( "file" );
655  variables.setCalendarFile( option );
656 
657  /*
658  * All modes need to know if the calendar file exists
659  * This must be done before we get to opening biz
660  */
661  bool exists, remote;
662  KURL url = KURL::fromPathOrURL( variables.getCalendarFile() );
663  if ( url.isLocalFile() ) {
664  variables.setCalendarFile( url.path() );
665  exists = TQFile::exists( variables.getCalendarFile() );
666  remote = false;
667  } else if ( url.protocol().isEmpty() ) {
668  TQFileInfo info( variables.getCalendarFile() );
669  variables.setCalendarFile( info.absFilePath() );
670  exists = TQFile::exists( variables.getCalendarFile() );
671  remote = false;
672  } else {
673  exists = true; // really have no idea if the remote file exists
674  remote = true;
675  }
676 
677  if ( create ) {
678 
679  kdDebug() << "main | createcalendar | "
680  << "check if calendar file already exists"
681  << endl;
682 
683  if ( remote ) {
684  cout << i18n( "Attempting to create a remote file %1" ).
685  arg( variables.getCalendarFile() ).local8Bit().data() << endl;
686  return 1;
687  } else {
688  if ( exists ) {
689  cout << i18n( "Calendar %1 already exists" ).
690  arg( variables.getCalendarFile() ).local8Bit().data()
691  << endl;
692  return 1;
693  }
694  }
695 
696  if ( konsolekalendar->createCalendar() ) {
697  cout << i18n( "Calendar %1 successfully created" ).
698  arg( variables.getCalendarFile() ).local8Bit().data()
699  << endl;
700  return 0;
701  } else {
702  cout << i18n( "Unable to create calendar: %1" ).
703  arg( variables.getCalendarFile() ).local8Bit().data()
704  << endl;
705  return 1;
706  }
707  }
708 
709  if ( !exists ) {
710  cout << i18n( "Calendar file not found %1" ).
711  arg( variables.getCalendarFile() ).local8Bit().data()
712  << endl;
713  cout << i18n( "Try --create to create new calendar file" ).local8Bit().data()
714  << endl;
715  return 1;
716  }
717  }
718 
719  CalendarResources *calendarResource = NULL;
720  /*
721  * Should we use local calendar or resource?
722  */
723  if ( args->isSet( "file" ) ) {
724  calendarResource = new StdCalendar( variables.getCalendarFile(),
725  i18n( "Active Calendar" ) );
726  } else {
727  // TODO: when certain resources (kolab) don't try to gain access to
728  // an X server, or dcopserver, then put back the following line which
729  // supports all resources, not just the standard resource.
730  // calendarResource = new StdCalendar();
731  calendarResource = new StdCalendar( locateLocal( "data",
732  "korganizer/std.ics" ),
733  i18n( "Default Calendar" ) );
734  }
735  if ( !args->isSet( "import" ) ) {
736  variables.setCalendar( calendarResource );
737  calendarResource->load();
738  }
739 
740  /***************************************************************************
741  * Glorious date/time checking and setting code *
742  ***************************************************************************/
743  TQDateTime startdatetime, enddatetime;
744 
745  // Handle case with either date or end-date unspecified
746  if ( !args->isSet( "end-date" ) && !args->isSet( "show-next" ) &&
747  args->isSet( "date" ) ) {
748  enddate = startdate;
749  kdDebug() << "main | datetimestamp | "
750  << "setting enddate to startdate"
751  << endl;
752  } else if ( args->isSet( "end-date" ) && !args->isSet( "date" ) ) {
753  startdate = enddate;
754  kdDebug() << "main | datetimestamp | "
755  << "setting startdate to enddate"
756  << endl;
757  }
758 
759  // NOTE: If neither date nor end-date specified, then event will be today.
760 
761  // Case:
762  // End time (or epoch) unspecified, and start time (or epoch) IS specified.
763  // In this case, set the ending to 1 hour after starting.
764  if ( !args->isSet( "end-time" ) && !args->isSet( "epoch-end" ) ) {
765  if ( args->isSet( "time" ) ) {
766  endtime = starttime.addSecs( 60 * 60 ); // end is 1 hour after start
767  kdDebug() << "main | datetimestamp | "
768  << "setting endtime 1 hour after starttime"
769  << endl;
770  } else if ( args->isSet( "epoch-start" ) ) {
771  startdatetime = epochs.epoch2TQDateTime( epochstart );
772  enddatetime = startdatetime.addSecs( 60 * 60 );
773  kdDebug() << "main | datetimestamp | "
774  << "setting endtime 1 hour after epochstart"
775  << endl;
776  }
777  }
778 
779  // Case:
780  // Time (or epoch) unspecified, and end-time (or epoch) IS specified.
781  // In this case, set the starting to 1 hour before ending.
782  if ( !args->isSet( "time" ) && !args->isSet( "epoch-start" ) ) {
783  if ( args->isSet( "end-time" ) ) {
784  starttime = endtime.addSecs( -60 * 60 ); // start is 1 hour before end
785  kdDebug() << "main | datetimestamp | "
786  << "setting starttime 1 hour before endtime"
787  << endl;
788  } else if ( args->isSet( "epoch-end" ) ) {
789  enddatetime = epochs.epoch2TQDateTime( epochend );
790  startdatetime = enddatetime.addSecs( -60 * 60 );
791  kdDebug() << "main | datetimestamp | "
792  << "setting starttime 1 before after epochend"
793  << endl;
794  }
795  }
796 
797  // Case:
798  // Time (or epoch) unspecified, and end-time (or epoch) unspecified.
799  if ( !args->isSet( "time" ) && !args->isSet( "epoch-start" ) &&
800  !args->isSet( "end-time" ) && !args->isSet( "epoch-end" ) ) {
801  // set default start date/time
802  startdatetime = TQDateTime( startdate, starttime );
803  kdDebug() << "main | datetimestamp | "
804  << "setting startdatetime from "
805  << "default startdate (today) and starttime"
806  << endl;
807  // set default end date/time
808  enddatetime = TQDateTime( enddate, endtime );
809  kdDebug() << "main | datetimestamp | "
810  << "setting enddatetime from "
811  << "default enddate (today) and endtime"
812  << endl;
813  }
814 
815  // Set startdatetime, enddatetime if still necessary
816  if ( startdatetime.isNull() ) {
817  startdatetime = TQDateTime( startdate, starttime );
818  kdDebug() << "main | datetimestamp | "
819  << "setting startdatetime from startdate and starttime"
820  << endl;
821  }
822  if ( enddatetime.isNull() ) {
823  enddatetime = TQDateTime( enddate, endtime );
824  kdDebug() << "main | datetimestamp | "
825  << "setting enddatetime from enddate and endtime"
826  << endl;
827  }
828 
829  // Float check for add mode:
830  // Events float if time AND end-time AND epoch times are UNspecified
831  if ( add ) {
832  if ( !args->isSet( "time" ) && !args->isSet( "end-time" ) &&
833  !args->isSet( "epoch-start" ) && !args->isSet( "epoch-end" ) ) {
834  variables.setFloating( true );
835  kdDebug() << "main | floatingcheck | "
836  << "turn-on floating event"
837  << endl;
838  }
839  }
840 
841  // Finally! Set the start/end date times
842  if ( !change ) {
843  variables.setStartDateTime( startdatetime );
844  variables.setEndDateTime( enddatetime );
845  } else {
846  // Do NOT set start/end datetimes in change mode,
847  // unless they were specified on commandline
848  if ( args->isSet( "time" ) || args->isSet( "epoch-start" ) ||
849  args->isSet( "end-time" ) || args->isSet( "epoch-end" ) ) {
850  variables.setStartDateTime( startdatetime );
851  variables.setEndDateTime( enddatetime );
852  }
853  }
854 
855  // Some more debug prints
856  kdDebug() << "main | datetimestamp | StartDate="
857  << startdatetime.toString( Qt::TextDate )
858  << endl;
859  kdDebug() << "main | datetimestamp | EndDate="
860  << enddatetime.toString( Qt::TextDate )
861  << endl;
862 
863  /***************************************************************************
864  * Sanity checks *
865  ***************************************************************************/
866 
867  // Cannot combine modes
868  if ( create + view + add + change + del > 1 ) {
869  cout << i18n(
870  "Only 1 operation mode "
871  "(view, add, change, delete, create) "
872  "permitted at any one time"
873  ).local8Bit().data() << endl;
874  return 1;
875  }
876 
877  // Cannot have a ending before starting
878  if ( startdatetime > enddatetime ) {
879  cout << i18n(
880  "Ending Date/Time occurs before the Starting Date/Time"
881  ).local8Bit().data() << endl;
882  return 1;
883  }
884 
885  /***************************************************************************
886  * And away we go with the real work... *
887  ***************************************************************************/
888 
889  args->clear(); // Free up some memory.
890 
891  /*
892  * Set our application name for use in unique IDs and error messages,
893  * and product ID for incidence PRODID property
894  */
895  TQString prodId = "-//K Desktop Environment//NONSGML %1 %2//EN";
896  CalFormat::setApplication( progDisplay,
897  prodId.arg( progDisplay ).arg( progVersion ) );
898 
899  if ( importFile ) {
900  if ( konsolekalendar->importCalendar() ) {
901  cout << i18n( "Calendar %1 successfully imported" ).
902  arg( variables.getImportFile() ).local8Bit().data()
903  << endl;
904  return 0;
905  } else {
906  cout << i18n( "Unable to import calendar: %1" ).
907  arg( variables.getImportFile() ).local8Bit().data()
908  << endl;
909  return 1;
910  }
911  }
912 
913  if ( add ) {
914  if ( !konsolekalendar->isEvent( startdatetime, enddatetime,
915  variables.getSummary() ) ) {
916  kdDebug() << "main | modework | "
917  << "calling addEvent()"
918  << endl;
919  konsolekalendar->addEvent();
920  } else {
921  cout << i18n(
922  "Attempting to insert an event that already exists"
923  ).local8Bit().data() << endl;
924  return 1;
925  }
926  }
927 
928  if ( change ) {
929  kdDebug() << "main | modework | "
930  << "calling changeEvent()"
931  << endl;
932  if ( !variables.isUID() ) {
933  cout << i18n( "Missing event UID: "
934  "use --uid command line option" ).local8Bit().data()
935  << endl;
936  return 1;
937  }
938  if ( konsolekalendar->changeEvent() != true ) {
939  cout << i18n( "No such event UID: change event failed" ).local8Bit().data()
940  << endl;
941  return 1;
942  }
943  kdDebug() << "main | modework | "
944  << "successful changeEvent()"
945  << endl;
946  }
947 
948  if ( del ) {
949  kdDebug() << "main | modework | "
950  << "calling deleteEvent()"
951  << endl;
952  if ( !variables.isUID() ) {
953  cout << i18n( "Missing event UID: "
954  "use --uid command line option" ).local8Bit().data()
955  << endl;
956  return 1;
957  }
958  if ( konsolekalendar->deleteEvent() != true ) {
959  cout << i18n( "No such event UID: delete event failed").local8Bit().data()
960  << endl;
961  return 1;
962  }
963  kdDebug() << "main | modework | "
964  << "successful deleteEvent()"
965  << endl;
966  }
967 
968  if ( view ) {
969  kdDebug() << "main | modework | "
970  << "calling showInstance() to view events"
971  << endl;
972  if ( !konsolekalendar->showInstance() ) {
973  cout << i18n( "Cannot open specified export file: %1" ).
974  arg( variables.getExportFile() ).local8Bit().data()
975  << endl;
976  return 1;
977  }
978  }
979 
980  delete konsolekalendar;
981 
982  calendarResource->close();
983  delete calendarResource;
984 
985  kdDebug() << "main | exiting"
986  << endl;
987 
988  return 0;
989 }