diff options
author | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
---|---|---|
committer | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
commit | 37333bf25ad9a4c538250f5af2f9f1d666362883 (patch) | |
tree | c45e8df5b9efbffe07eb3d9340df7811c7e16943 /kcron | |
download | tdeadmin-37333bf25ad9a4c538250f5af2f9f1d666362883.tar.gz tdeadmin-37333bf25ad9a4c538250f5af2f9f1d666362883.zip |
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdeadmin@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kcron')
61 files changed, 7644 insertions, 0 deletions
diff --git a/kcron/AUTHORS b/kcron/AUTHORS new file mode 100644 index 0000000..c182394 --- /dev/null +++ b/kcron/AUTHORS @@ -0,0 +1,2 @@ +Gary Meyer <gary@meyer.net> +Robert Berry <rjmber@ntlworld.com> diff --git a/kcron/COPYING b/kcron/COPYING new file mode 100644 index 0000000..37ba36f --- /dev/null +++ b/kcron/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) 19yy <name of author> + + 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 + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/kcron/ChangeLog b/kcron/ChangeLog new file mode 100644 index 0000000..b83a3eb --- /dev/null +++ b/kcron/ChangeLog @@ -0,0 +1,66 @@ +gary@meyer.net September 6, 1999 + + Fixed bug. Program didn't exit after editing. KDE2 only. + Fixed bug. Variable editor didn't update icon. KDE2 only. + Changed default sorting. Alphabetical with System Crontab on top. + Removed -lkfm from Makefile. + Change kcron.kdelnk to kcron.desktop. + +gary@meyer.net September 7, 1999 + + cttask.h, cttash.cpp, kttask.cpp + Fixed bug. New syscron task didn't let user enter "run as" field. + +gary@meyer.net September 10, 1999 + + Initial implementation of cut/copy/paste. + +gary@meyer.net September 17, 1999 + + Work around for Qt 2.0 ~QListViewItem bug. + +gary@meyer.net November 1, 1999 + + Released 0.5. + +gary@meyer.net November 7, 1999 + + Added KCron handbook. Various bug fixes. + +gary@meyer.net November 15, 1999 + + Fixed bug for supporting strftime (in CTTask::describe()) on different + platforms. + +gary@meyer.net November 19, 1999 + + Code clean up effort. + +gary@meyer.net November 29, 1999 + + Removed dependency on langinfo.h for internationalization of days of week + and months. Not broadly supported across platforms/distributions. + +gary@meyer.net December 2, 1999 + + Removed CTDebug, don't really need anymore. + Addeed note for translators so they'll look at README.translators. + Cleaned up CTUnit: moved implementation to cpp file, removed macro, + added support for "sun, Mon" and "jan, FEB" in crontab file. + +code@jamesots.com January 27, 2004 + + * Fixed bug. If only one hour wasn't checked '*' was still being used. + * Fixed bug. Removed autoWrap from KTVariable, as text is wrapped + in the line edit box anyway. Changed to use QTextEdit instead of the + deprecated QMultiLineEdit. + * Fixed bug. Strip out newlines from variable comments, because we + only read one line of comment from crontab for each entry. + * Fixed bug. System Crontab uses correct icon. + * Using standard icons for everything now. + * Added Set/Clear All buttons. + * Added New, Modify and Delete buttons on toolbar. (Bug 54399 and + part of bug 55684. Note about 55684: Use Ctrl-X as shortcut to delete + item.) + * Enabled New action when variables and tasks are selected, instead of + only when the containing label is selected. diff --git a/kcron/Makefile.am b/kcron/Makefile.am new file mode 100644 index 0000000..1cd898d --- /dev/null +++ b/kcron/Makefile.am @@ -0,0 +1,111 @@ +########################################################################## +# Makefile.am # +# -------------------------------------------------------------------- # +# Makefile.am for KCron # +# -------------------------------------------------------------------- # +# Copyright (C) 1999, Gary Meyer <gary@meyer.net> # +# -------------------------------------------------------------------- # +# 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. # +########################################################################## + +bin_PROGRAMS = kcron + +kcron_SOURCES = \ + cthost.cpp \ + ctcron.cpp \ + ctmonth.cpp \ + ctdom.cpp \ + ctdow.cpp \ + cttask.cpp \ + ctvariable.cpp \ + kticon.cpp \ + ktapp.cpp \ + ktview.cpp \ + ktlistitem.cpp \ + ktlistcron.cpp \ + ktlisttask.cpp \ + ktlisttasks.cpp \ + ktlistvar.cpp \ + ktlistvars.cpp \ + kttask.cpp \ + ktvariable.cpp \ + ktprint.cpp \ + ktprintopt.cpp \ + main.cpp + +EXTRA_DIST = \ + ctcron.cpp \ + ctcron.h \ + ctdom.cpp \ + ctdom.h \ + ctdow.cpp \ + ctdow.h \ + ctexception.h \ + cthost.cpp \ + cthost.h \ + cthour.h \ + cti18n.h \ + ctminute.h \ + ctmonth.cpp \ + ctmonth.h \ + cttask.cpp \ + cttask.h \ + ctunit.cpp \ + ctunit.h \ + ctvariable.cpp \ + ctvariable.h \ + ktapp.h \ + ktapp.cpp \ + kticon.h \ + kticon.cpp \ + kttask.h \ + kttask.cpp \ + ktvariable.h \ + ktvariable.cpp \ + ktview.cpp \ + ktview.h \ + ktlistitem.h \ + ktlistitem.cpp \ + ktlistcron.h \ + ktlistcron.cpp \ + ktlisttask.h \ + ktlisttask.cpp \ + ktlisttasks.h \ + ktlisttasks.cpp \ + ktlistvar.h \ + ktlistvar.cpp \ + ktlistvars.h \ + ktlistvars.cpp \ + ktprint.h \ + ktprint.cpp \ + ktprintopt.h \ + ktprintopt.cpp \ + main.cpp \ + README \ + AUTHORS \ + COPYING \ + ChangeLog \ + TODO \ + kcron.desktop \ + kcron.lsm \ + Makefile.am + +INCLUDES= $(all_includes) + +kcron_METASOURCES = AUTO + +kcron_LDFLAGS = $(all_libraries) $(KDE_RPATH) + +messages: rc.cpp + $(XGETTEXT) *.cpp -o $(podir)/kcron.pot + +kcron_LDADD = $(LIB_KFILE) -lkdeprint + +xdg_apps_DATA = kcron.desktop + +KDE_ICON = kcron +shellrcdir = $(kde_datadir)/kcron +shellrc_DATA = kcronui.rc diff --git a/kcron/README b/kcron/README new file mode 100644 index 0000000..ffcc015 --- /dev/null +++ b/kcron/README @@ -0,0 +1,12 @@ +KCron + +KDE Task Scheduler + +GUI crontab editor + +Requires: + + Unix POSIX libraries for localized dates and times (glibc) + Cron (vixie-cron) + Crontab (crontabs) + diff --git a/kcron/README.hacking b/kcron/README.hacking new file mode 100644 index 0000000..daa9c74 --- /dev/null +++ b/kcron/README.hacking @@ -0,0 +1,8 @@ +README.hacking + +Author: Gary Meyer <gary@meyer.net> +Date: November 15, 1999 + +--------------------------------------------------------------------------- +Do not introduce any Qt or KDE dependencies into the "CT"-prefixed classes. +I want to be able to reuse those classes with another GUI toolkit. diff --git a/kcron/README.translators b/kcron/README.translators new file mode 100644 index 0000000..87c4d71 --- /dev/null +++ b/kcron/README.translators @@ -0,0 +1,109 @@ +README.translators + +Author: Gary Meyer <gary@meyer.net> +Date: November 7, 1999 + +--------------------------------------------------------------------------- +KCron requires special care in translation. KCron does natural language +description, such as "At 12:00am, every day." How days and times are +described in different languages and cultures varies greatly. + +I have tried to accomodate this challenge through making formatting of the +display significantly controlled by the translater. + +The approach I have taken makes formatting strings available to the +translator. Where there is a string to translate that has a name +"SUCH_AS_THIS", KCron treats "SUCH_AS_THIS" as a special token. + +For instance, consider "DAYS_OF_MONTH of MONTHS". The translator can +move the ordering of the phrases around. Additionally the translator +can translate the various words as well as separators such as the comma. +--------------------------------------------------------------------------- +Look at CTTask::describe(). This is the most significant method used in +creating the description string that appears in the main display. + +1. Change "%l:%M%P" to support time formatting for your locale. + +Default: + "%l:%M%P" -> "11:00pm" + +Other possibilities: + "%l:%M%p" -> "11:00PM" + "%H:%M" -> "23:00" + +See "man strftime" for more time formatting options available. + +2. Change "DAYS_OF_MONTH of MONTHS" to support how days of the month are +combined with month names for your locale. + +Default: + "DAYS_OF_MONTH of MONTHS" -> "1st and 15th of Jan" + +Other possibilities: + "MONTHS, DAYS_OF_MONTH" -> "Jan, 1st and 15th" + +3. Change "every DAYS_OF_WEEK" to support how the English phrase +"every Monday" is translated to your locale. + +Default: + "every DAYS_OF_WEEK" -> "every Mon, Wed, and Fri" + +Other possibilitities: + "DAYS_OF_WEEK" -> "Mon, Wed, and Fri" + +4. Change "DOM_FORMAT as well as DOW_FORMAT" to support how complex +phrases that involve day of the month as well as day of the week are +described in your locale. + +Default: + "DOM_FORMAT as well as DOW_FORMAT" -> "1st and 15th of every month as well + as every Sun" + +Other possibilities: + "DOM_FORMAT and DOW_FORMAT" -> "1st and 15th of every month and every Sun" + +Note how the order of the two phrases can be changed. + +5. Change "At TIME" to support how the English phrase "At 11:00pm" is +translated to your locale. + +Default: + "At TIME" -> "At 11:00pm" + +Other possibilities: + "TIME" -> "11:00pm" + +If necessary you can put a phrase suffix after the "TIME" token. + +6. Change "TIME_FORMAT, DATE_FORMAT" to describe how the English phrase +"At 11:00pm, every Sun" is best translated to your locale. + +Default: + "TIME_FORMAT, DATE_FORMAT" -> "At 11:00pm, every Sun" + +Other possibilities: + "TIME_FORMAT DATE_FORMAT" -> "At 11:00pm every Sun" + "DATE_FORMAT TIME_FORMAT" -> "every Sun At 11:00pm" + +So the following translations... + "%l:%M%P" -> "%H:%M" + "DAYS_OF_MONTH of MONTHS" -> "MONTHS DAYS_OF_MONTH" + "every DAYS_OF_WEEK" -> "every DAYS_OF_WEEK" + "DOM_FORMAT as well as DOW_FORMAT" -> "DOM_FORMAT and DOW_FORMAT" + "At TIME" -> "at TIME" -> + "TIME_FORMAT, DATE_FORMAT" -> "DATE_FORMAT TIME_FORMAT" + +Would produce... + "Jan 1st 23:00" instead of "At 11:00pm, Jan 1st" +--------------------------------------------------------------------------- +ctunit.h and cttask.cpp also have places to describe whether or not +your local uses: + + "1, 2, and 3" or + "1, 2 and 3" or + "1, 2, 3" +--------------------------------------------------------------------------- +Everything else should be rather clear to translate. If you can not +support your locale through this translation, email the author at +gary@meyer.net and I'll see if I can make changes to accomodate. + diff --git a/kcron/TODO b/kcron/TODO new file mode 100644 index 0000000..6939a1c --- /dev/null +++ b/kcron/TODO @@ -0,0 +1,7 @@ +Features to be added: + +- Import/export crontab file +- View man page of task command +- Edit task command if an editable script +- New task wizard + diff --git a/kcron/configure.in.in b/kcron/configure.in.in new file mode 100644 index 0000000..be677e4 --- /dev/null +++ b/kcron/configure.in.in @@ -0,0 +1,4 @@ +AC_LANG_SAVE +AC_LANG_CPLUSPLUS +AC_CHECK_HEADERS(sstream) +AC_LANG_RESTORE diff --git a/kcron/ctcron.cpp b/kcron/ctcron.cpp new file mode 100644 index 0000000..853f6de --- /dev/null +++ b/kcron/ctcron.cpp @@ -0,0 +1,333 @@ +/*************************************************************************** + * CT Cron Implementation * + * -------------------------------------------------------------------- * + * Copyright (C) 1999, Gary Meyer <gary@meyer.net> * + * -------------------------------------------------------------------- * + * 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. * + ***************************************************************************/ + +// Do not introduce any Qt or KDE dependencies into the "CT"-prefixed classes. +// I want to be able to reuse these classes with another GUI toolkit. -GM 11/99 + +#include "ctcron.h" + +#include "cti18n.h" +#include "cttask.h" +#include "ctvariable.h" +#include <unistd.h> // getuid(), unlink() +#include <pwd.h> // pwd, getpwnam(), getpwuid() +#include <stdio.h> +#include <assert.h> + +#include <qfile.h> + +#include <kprocess.h> +#include <klocale.h> +#include <ktempfile.h> + +#include <iostream> + +using namespace std; + +CTCron::CTCron(bool _syscron, string _login) : + syscron(_syscron) +{ + int uid(getuid()); + + KTempFile tmp; + tmp.setAutoDelete(true); + tmp.close(); + tmpFileName = tmp.name(); + + QString readCommand; + + if (uid == 0) + // root, so provide requested crontab + { + if (syscron) + { + readCommand = "cat /etc/crontab > " + KProcess::quote(tmpFileName); + writeCommand = "cat " + KProcess::quote(tmpFileName) + " > /etc/crontab"; + login = (const char *)i18n("(System Crontab)").local8Bit(); + name = ""; + } + else + { + readCommand = QString("crontab -u ") + _login.c_str() + " -l > " + KProcess::quote(tmpFileName); + writeCommand = QString("crontab -u ") + _login.c_str() + " " + KProcess::quote(tmpFileName); + if (!initFromPasswd(getpwnam(_login.c_str()))) + { + error = i18n("No password entry found for user '%1'").arg(_login.c_str()); + } + } + } + else + // regular user, so provide user's own crontab + { + readCommand = "crontab -l > " + KProcess::quote(tmpFileName); + writeCommand = "crontab " + KProcess::quote(tmpFileName); + if (!initFromPasswd(getpwuid(uid))) + { + error = i18n("No password entry found for uid '%1'").arg(uid); + } + } + + if (name.empty()) + name = login; + + initialTaskCount = 0; + initialVariableCount = 0; + + if (isError()) + return; + + // Don't set error if it can't be read, it means the user + // doesn't have a crontab. + if (system(QFile::encodeName(readCommand)) == 0) + { + ifstream cronfile(QFile::encodeName(tmpFileName)); + cronfile >> *this; + } + + initialTaskCount = task.size(); + initialVariableCount = variable.size(); +} + +CTCron::CTCron(const struct passwd *pwd) : + syscron(false) +{ + Q_ASSERT(pwd != 0L); + + KTempFile tmp; + tmp.setAutoDelete(true); + tmp.close(); + tmpFileName = tmp.name(); + + QString readCommand = QString("crontab -u ") + QString(pwd->pw_name) + " -l > " + KProcess::quote(tmpFileName); + writeCommand = QString("crontab -u ") + QString(pwd->pw_name) + " " + KProcess::quote(tmpFileName); + + initFromPasswd(pwd); + + initialTaskCount = 0; + initialVariableCount = 0; + + if (isError()) + return; + + // Don't set error if it can't be read, it means the user + // doesn't have a crontab. + if (system(QFile::encodeName(readCommand)) == 0) + { + ifstream cronfile(QFile::encodeName(tmpFileName)); + cronfile >> *this; + } + + initialTaskCount = task.size(); + initialVariableCount = variable.size(); +} + +bool CTCron::initFromPasswd(const struct passwd *pwd) +{ + if (pwd == 0) + { + return false; + } + else + { + login = pwd->pw_name; + name = pwd->pw_gecos; + return true; + } +} + +void CTCron::operator = (const CTCron& source) +{ + assert(!source.syscron); + + for (CTVariableIterator i = const_cast<CTCron&>(source).variable.begin(); + i != source.variable.end(); ++i) + { + CTVariable* tmp = new CTVariable(**i); + variable.push_back(tmp); + } + + for (CTTaskIterator i = const_cast<CTCron&>(source).task.begin(); + i != source.task.end(); ++i) + { + CTTask* tmp = new CTTask(**i); + task.push_back(tmp); + } +} + +istream& operator >> (istream& inputStream, CTCron& cron) +{ + const int MAX = 1024; + char buffer[MAX]; + string line(""); + string comment(""); + + while (inputStream) + { + inputStream.getline(buffer, MAX); + line = buffer; + + // search for comments "#" but not disabled tasks "#\" + if ((line.find("#") == 0) && (line.find("\\") != 1)) + { + // If the first 10 characters don't contain a character, it's probably a disabled entry. + int first_text = line.find_first_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); + if (first_text < 0) + continue; + + if (first_text < 10) + { + // remove leading pound sign + line = line.substr(1,line.length()-1); + // remove leading whitespace + while (line.find_first_of(" \t") == 0) + line = line.substr(1,line.length()-1); + comment = line; + continue; + } + } + + // else + { + // either a task or a variable + int firstWhiteSpace(line.find_first_of(" \t")); + int firstEquals(line.find("=")); + + // if there is an equals sign and either there is no + // whitespace or the first whitespace is after the equals + // sign, it must be a variable + if ((firstEquals > 0) && ((firstWhiteSpace == -1) || + firstWhiteSpace > firstEquals)) + { + // create variable + CTVariable *tmp = new CTVariable(line, comment); + cron.variable.push_back(tmp); + comment = ""; + } + else + // must be a task, either enabled or disabled + { + if (firstWhiteSpace > 0) + { + CTTask *tmp = new CTTask(line, comment, cron.syscron); + cron.task.push_back(tmp); + comment = ""; + } + } + } + } + return inputStream; +} + +ostream& operator << (ostream& outputStream, const CTCron& cron) +{ + int itemCount(0); + + for (CTVariableIterator i = const_cast<CTCron&>(cron).variable.begin(); + i != cron.variable.end(); ++i) + { + outputStream << **i; + itemCount++; + } + + for (CTTaskIterator i = const_cast<CTCron&>(cron).task.begin(); + i != cron.task.end(); ++i) + { + outputStream << **i; + itemCount++; + } + + if (itemCount > 0) + { + outputStream << "# This file was written by KCron. Copyright (c) 1999, Gary Meyer\n"; + outputStream << "# Although KCron supports most crontab formats, use care when editing.\n"; + outputStream << "# Note: Lines beginning with \"#\\\" indicates a disabled task.\n"; + } + + return outputStream; +} + +CTCron::~CTCron() +{ + for (CTTaskIterator i = task.begin(); i != task.end(); ++i) + delete *i; + for (CTVariableIterator i = variable.begin(); i != variable.end(); ++i) + delete *i; +} + +void CTCron::apply() +{ + // write to temp file + ofstream cronfile(QFile::encodeName(tmpFileName)); + cronfile << *this << flush; + + // install temp file into crontab + if (system(QFile::encodeName(writeCommand)) != 0) + { + error = i18n("An error occurred while updating crontab."); + } + + // remove the temp file + (void) unlink(QFile::encodeName(tmpFileName)); + + if (isError()) + return; + + // mark as applied + for (CTTaskIterator i = task.begin(); i != task.end(); ++i) + (*i)->apply(); + + for (CTVariableIterator i = variable.begin(); i != variable.end(); ++i) + (*i)->apply(); + + initialTaskCount = task.size(); + initialVariableCount = variable.size(); +} + +void CTCron::cancel() +{ + for (CTTaskIterator i = task.begin(); i != task.end(); ++i) + (*i)->cancel(); + + for (CTVariableIterator i = variable.begin(); i != variable.end(); ++i) + (*i)->cancel(); +} + +bool CTCron::dirty() +{ + bool isDirty(false); + + if (initialTaskCount != task.size()) isDirty = true; + + if (initialVariableCount != variable.size()) isDirty = true; + + for (CTTaskIterator i = task.begin(); i != task.end(); ++i) + if ((*i)->dirty()) isDirty = true; + + for (CTVariableIterator i = variable.begin(); i != variable.end(); ++i) + if ((*i)->dirty()) isDirty = true; + + return isDirty; +} + +string CTCron::path() const +{ + string path; + + for (CTVariableIterator var = const_cast<CTCron*>(this)->variable.begin(); + var != variable.end(); var++) + { + if ((*var)->variable == "PATH") + { + path = (*var)->value; + } + } + return path; +} diff --git a/kcron/ctcron.h b/kcron/ctcron.h new file mode 100644 index 0000000..b8d03fe --- /dev/null +++ b/kcron/ctcron.h @@ -0,0 +1,154 @@ +/*************************************************************************** + * CT Cron Header * + * -------------------------------------------------------------------- * + * Copyright (C) 1999, Gary Meyer <gary@meyer.net> * + * -------------------------------------------------------------------- * + * 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. * + ***************************************************************************/ + +#ifndef CTCRON_H +#define CTCRON_H + +// Do not introduce any Qt or KDE dependencies into the "CT"-prefixed classes. +// I want to be able to reuse these classes with another GUI toolkit. -GM 11/99 + +#include <vector> +#include <string> +#include <iostream> + +#include <qstring.h> // Anarchy! -WABA + +class CTException; +class CTTask; +class CTVariable; + +struct passwd; + +/** + * A user (encapsulation of a single crontab file). Encapsulates + * file i/o, parsing, tokenization, and natural language description. + */ +class CTCron +{ +public: + +/** + * Constructs the scheduled tasks, environment variables from crontab + * files and obtains some information about the user from the system. + * + * Default is to construct from the user's crontab. Can also be called, + * passing TRUE, to construct from the system crontab. Throws an + * exception if the crontab file can not be found, read, or parsed. + */ + CTCron(bool _syscron = false, std::string _login = ""); +/** + * If you already have a struct passwd, use it instead. This + * is never used for the system crontab. + */ + CTCron(const struct passwd * _login = 0L); + +/** + * Copy one user's tasks and environement variables to another user. + */ + void operator = (const CTCron& source); + +/** + * Parses crontab file format. + */ + friend std::istream& operator >> (std::istream& inputStream, CTCron& cron); + +/** + * Tokenizes to crontab file format. + */ + friend std::ostream& operator << (std::ostream& outputStream, const CTCron& cron); + +/** + * Apply changes. + */ + void apply(); + +/** + * Cancel changes. + */ + void cancel(); + +/** + * Indicates whether or not dirty. + */ + bool dirty(); + +/** + * Returns the PATH environment variable value. A short cut to iterating + * the tasks vector. + */ + std::string path() const; + + /** + * Returns whether an error has occured + */ + bool isError() { return !error.isEmpty(); } + + /** + * Return error description + */ + QString errorMessage() { QString r = error; error = QString::null; return r; } + + +/** + * Indicates whether or not the crontab belongs to the system. + */ + const bool syscron; + +/** + * User login. + */ + std::string login; + +/** + * User real name. + */ + std::string name; + +/** + * User's scheduled tasks. + */ + std::vector<CTTask *> task; + +/** + * User's environment variables. Note: These are only environment variables + * found in the user's crontab file and does not include any set in a + * login or shell script such as ".bash_profile". + */ + std::vector<CTVariable *> variable; + +/** + * Destructor. + */ + ~CTCron(); + +private: + +/** + * Can't copy a user! + */ + CTCron(const CTCron& source); + + unsigned int initialTaskCount; + unsigned int initialVariableCount; + QString writeCommand; + QString tmpFileName; + + QString error; + +protected: + // Initialize member variables from the struct passwd. + bool initFromPasswd(const struct passwd *); +}; + +typedef std::vector<CTTask*>::iterator CTTaskIterator; +typedef std::vector<CTVariable*>::iterator CTVariableIterator; + +#endif // CTCRON_H diff --git a/kcron/ctdom.cpp b/kcron/ctdom.cpp new file mode 100644 index 0000000..b1d7f5e --- /dev/null +++ b/kcron/ctdom.cpp @@ -0,0 +1,73 @@ +/*************************************************************************** + * CT Day of Month Implementation * + * -------------------------------------------------------------------- * + * Copyright (C) 1999, Gary Meyer <gary@meyer.net> * + * -------------------------------------------------------------------- * + * 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. * + ***************************************************************************/ + +// Do not introduce any Qt or KDE dependencies into the "CT"-prefixed classes. +// I want to be able to reuse these classes with another GUI toolkit. -GM 11/99 + +#include "ctdom.h" +#include "cti18n.h" + +string CTDayOfMonth::shortName[32] = +{ + "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" +}; + +CTDayOfMonth::CTDayOfMonth(const string& tokStr) : + CTUnit<1,31>(tokStr) +{ +} + +string CTDayOfMonth::describe() const +{ + initializeNames(); + return (count() == 31) ? + (const char*)i18n("every day ").local8Bit() : + CTUnit<1,31>::describe(shortName); +} + +string CTDayOfMonth::getName(const int ndx) +{ + initializeNames(); + return shortName[ndx]; +} + +void CTDayOfMonth::initializeNames() +{ + if (shortName[1].empty()) + { + const string shortDOMName[32] = + { + "", + (const char*)i18n("1st").local8Bit(), (const char*)i18n("2nd").local8Bit(), + (const char*)i18n("3rd").local8Bit(), (const char*)i18n("4th").local8Bit(), + (const char*)i18n("5th").local8Bit(), (const char*)i18n("6th").local8Bit(), + (const char*)i18n("7th").local8Bit(), (const char*)i18n("8th").local8Bit(), + (const char*)i18n("9th").local8Bit(), (const char*)i18n("10th").local8Bit(), + (const char*)i18n("11th").local8Bit(), (const char*)i18n("12th").local8Bit(), + (const char*)i18n("13th").local8Bit(), (const char*)i18n("14th").local8Bit(), + (const char*)i18n("15th").local8Bit(), (const char*)i18n("16th").local8Bit(), + (const char*)i18n("17th").local8Bit(), (const char*)i18n("18th").local8Bit(), + (const char*)i18n("19th").local8Bit(), (const char*)i18n("20th").local8Bit(), + (const char*)i18n("21st").local8Bit(), (const char*)i18n("22nd").local8Bit(), + (const char*)i18n("23rd").local8Bit(), (const char*)i18n("24th").local8Bit(), + (const char*)i18n("25th").local8Bit(), (const char*)i18n("26th").local8Bit(), + (const char*)i18n("27th").local8Bit(), (const char*)i18n("28th").local8Bit(), + (const char*)i18n("29th").local8Bit(), (const char*)i18n("30th").local8Bit(), + (const char*)i18n("31st").local8Bit() + }; + + for (int i = 1; i <= 31; i++) + { + shortName[i] = shortDOMName[i]; + } + } +} diff --git a/kcron/ctdom.h b/kcron/ctdom.h new file mode 100644 index 0000000..4e66747 --- /dev/null +++ b/kcron/ctdom.h @@ -0,0 +1,62 @@ +/*************************************************************************** + * CT Day of Month Header * + * -------------------------------------------------------------------- * + * Copyright (C) 1999, Gary Meyer <gary@meyer.net> * + * -------------------------------------------------------------------- * + * 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. * + ***************************************************************************/ + +#ifndef CTDOM_H +#define CTDOM_H + +// Do not introduce any Qt or KDE dependencies into the "CT"-prefixed classes. +// I want to be able to reuse these classes with another GUI toolkit. -GM 11/99 + +#include "ctunit.h" +#include <string> + +/** + * Scheduled task days of month. + */ +class CTDayOfMonth : public CTUnit<1,31> +{ +public: +/** + * Constructs from a tokenized string. + */ + CTDayOfMonth(const string& tokStr = ""); + +/** + * Default copy constructor. + */ + // CTDayOfMonth(const CTDayOfMonth& source); + +/** + * Default assignment operator + */ + // void operator = (const CTDayOfMonth& source); + +/** + * Default destructor. + */ + // ~CTDayOfMonth(); + +/** + * Get natural language description. + */ + virtual string describe() const; + +/** + * Get day of month name. + */ + static string getName(const int ndx); + +private: + static void initializeNames(); + static string shortName[32]; +}; + +#endif // CTDOM_H diff --git a/kcron/ctdow.cpp b/kcron/ctdow.cpp new file mode 100644 index 0000000..fe93c86 --- /dev/null +++ b/kcron/ctdow.cpp @@ -0,0 +1,99 @@ +/*************************************************************************** + * CT Day Of Week Implementation * + * -------------------------------------------------------------------- * + * Copyright (C) 1999, Gary Meyer <gary@meyer.net> * + * -------------------------------------------------------------------- * + * 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. * + ***************************************************************************/ + +// Do not introduce any Qt or KDE dependencies into the "CT"-prefixed classes. +// I want to be able to reuse these classes with another GUI toolkit. -GM 11/99 + +#include "ctdow.h" +#include "cti18n.h" + +string CTDayOfWeek::shortName[8] = +{ + "", "", "", "", "", "", "", "" +}; + +string CTDayOfWeek::longName[8] = +{ + "", "", "", "", "", "", "", "" +}; + +CTDayOfWeek::CTDayOfWeek(const string& tokStr) : + CTUnit<1,7>(tokStr) +{ + // Compensate for cron supporting Sunday as both 0 and 7. + + if (get(0)) + { + set(0,false); + set(7,true); + } +} + +void CTDayOfWeek::initialize(const string &tokStr) +{ + CTUnit<1,7>::initialize(tokStr); + + // Compensate for cron supporting Sunday as both 0 and 7. + + if (get(0)) + { + set(0,false); + set(7,true); + apply(); + } +} + +string CTDayOfWeek::describe() const +{ + initializeNames(); + if (count() == 7) + return (const char*)i18n("every day ").local8Bit(); + else if (get(1) && get(2) && get(3) && get(4) && get(5)) + return (const char*)i18n("weekday ").local8Bit(); + else + return CTUnit<1,7>::describe(shortName); +} + +string CTDayOfWeek::getName(const int ndx, const bool format) +{ + initializeNames(); + return (format == shortFormat) ? shortName[ndx] : longName[ndx]; +} + +void CTDayOfWeek::initializeNames() +{ + if (shortName[1].empty()) + { + const string shortDOWName[8] = + { + "", + (const char*)i18n("Mon").local8Bit(), (const char*)i18n("Tue").local8Bit(), + (const char*)i18n("Wed").local8Bit(), (const char*)i18n("Thu").local8Bit(), + (const char*)i18n("Fri").local8Bit(), (const char*)i18n("Sat").local8Bit(), + (const char*)i18n("Sun").local8Bit() + }; + + const string longDOWName[8] = + { + "", + (const char*)i18n("Monday").local8Bit(), (const char*)i18n("Tuesday").local8Bit(), + (const char*)i18n("Wednesday").local8Bit(), (const char*)i18n("Thursday").local8Bit(), + (const char*)i18n("Friday").local8Bit(), (const char*)i18n("Saturday").local8Bit(), + (const char*)i18n("Sunday").local8Bit() + }; + + for (int i = 1; i <= 7; i++) + { + shortName[i] = shortDOWName[i]; + longName[i] = longDOWName[i]; + } + } +} diff --git a/kcron/ctdow.h b/kcron/ctdow.h new file mode 100644 index 0000000..05b6357 --- /dev/null +++ b/kcron/ctdow.h @@ -0,0 +1,70 @@ +/*************************************************************************** + * CT Day of Week Header * + * -------------------------------------------------------------------- * + * Copyright (C) 1999, Gary Meyer <gary@meyer.net> * + * -------------------------------------------------------------------- * + * 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. * + ***************************************************************************/ + +#ifndef CTDOW_H +#define CTDOW_H + +// Do not introduce any Qt or KDE dependencies into the "CT"-prefixed classes. +// I want to be able to reuse these classes with another GUI toolkit. -GM 11/99 + +#include "ctunit.h" +#include <string> + +/** + * Scheduled task days of week. + */ +class CTDayOfWeek : public CTUnit<1,7> +{ +public: +/** + * Constructs from a tokenized string. + */ + CTDayOfWeek(const string& tokStr = ""); + +/** + * Default copy constructor. + */ + // CTDayOfWeek(const CTDayOfWeek& source); + +/** + * Default assignment operator + */ + // void operator = (const CTDayOfWeek& source); + +/** + * Default destructor. + */ + // ~CTDayOfWeek(); + +/** + * Override initialize to support crontab using both 0 and 7 for + * Sunday. + */ + void initialize(const string &tokStr = ""); + +/** + * Get natural language description. + */ + virtual string describe() const; + +/** + * Get day of week name. + */ + static string getName(const int ndx, + const bool format = CTDayOfWeek::longFormat); + +private: + static void initializeNames(); + static string shortName[8]; + static string longName[8]; +}; + +#endif // CTDOW_H diff --git a/kcron/cthost.cpp b/kcron/cthost.cpp new file mode 100644 index 0000000..356047d --- /dev/null +++ b/kcron/cthost.cpp @@ -0,0 +1,117 @@ +/*************************************************************************** + * -------------------------------------------------------------------- * + * CT Host Implementation * + * -------------------------------------------------------------------- * + * Copyright (C) 1999, Gary Meyer <gary@meyer.net> * + * -------------------------------------------------------------------- * + * 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. * + ***************************************************************************/ + +// Do not introduce any Qt or KDE dependencies into the "CT"-prefixed classes. +// I want to be able to reuse these classes with another GUI toolkit. -GM 11/99 + +#include "cthost.h" + +#include "ctcron.h" + +#include <unistd.h> // getuid() + +#include <sys/types.h> +#include <pwd.h> + + +using namespace std; + +CTHost::CTHost() +{ + struct passwd *pwd = 0L; + + // If it is the root user + if (getuid() == 0) + { + // Create the system cron table. + createCTCron(true); + + // Read /etc/passwd + setpwent(); // restart + while((pwd=getpwent())) + { + createCTCron(pwd); + } + setpwent(); // restart again for others + } + else + // Non-root user, so just create user's cron table. + { + createCTCron(); + } +} + +CTHost::~CTHost() +{ + for (CTCronIterator i = cron.begin(); i != cron.end(); ++i) + delete *i; +} + +void CTHost::apply() +{ + for (CTCronIterator i = cron.begin(); i != cron.end(); ++i) + { + (*i)->apply(); + if ((*i)->isError()) + { + error = (*i)->errorMessage(); + return; + } + } +} + +void CTHost::cancel() +{ + for (CTCronIterator i = cron.begin(); i != cron.end(); ++i) + (*i)->cancel(); +} + +bool CTHost::dirty() +{ + bool isDirty(false); + + for (CTCronIterator i = cron.begin(); i != cron.end(); ++i) + if ((*i)->dirty()) isDirty = true; + + return isDirty; +} + +CTCron* CTHost::createCTCron(bool _syscron, string _login) +{ + CTCron *p = new CTCron(_syscron, _login); + if (p->isError()) + { + error = p->errorMessage(); + delete p; + return 0; + } + cron.push_back(p); + return p; +} + +CTCron* CTHost::createCTCron(const struct passwd *pwd) +{ + CTCron *p = new CTCron(pwd); + if (p->isError()) + { + error = p->errorMessage(); + delete p; + return 0; + } + cron.push_back(p); + return p; +} + +bool CTHost::root() const +{ + return (!getuid()); +} diff --git a/kcron/cthost.h b/kcron/cthost.h new file mode 100644 index 0000000..6d601c3 --- /dev/null +++ b/kcron/cthost.h @@ -0,0 +1,118 @@ +/*************************************************************************** + * CT Host Header * + * -------------------------------------------------------------------- * + * Copyright (C) 1999, Gary Meyer <gary@meyer.net> * + * -------------------------------------------------------------------- * + * 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. * + ***************************************************************************/ + +#ifndef CTHOST_H +#define CTHOST_H + +// Do not introduce any Qt or KDE dependencies into the "CT"-prefixed classes. +// I want to be able to reuse these classes with another GUI toolkit. -GM 11/99 + +#include <vector> +#include <string> + +#include <qstring.h> // Whatever + +class CTCron; +struct passwd; + +/** + * The host machine, or computer (encapsulation of crontab files on the + * host). + * + * If the user is the root user, the cron vector will have a member for + * each user of the host plus one for the system crontab. + * + * If the user is a non-root user, there will be only one member in the + * cron vector. + */ +class CTHost +{ +public: + +/** + * Constructs the user(s), scheduled tasks, and environment variables + * from crontab files. + */ + CTHost(); + +/** + * Destroys the user(s), scheduled tasks, and environment variable + * objects. Does not make any changes to the crontab files. Any unapplied + * changes are consequently "cancelled." + */ + ~CTHost(); + +/** + * Apply changes. + */ + void apply(); + +/** + * Cancel changes. + */ + void cancel(); + +/** + * Indicates whether or not dirty. + */ + bool dirty(); + +/** + * Indicates whether or not the user is the root user. + */ + bool root() const; + +/** + * Indicates an error has occured. + */ + bool isError() { return !error.isEmpty(); } + +/** + * Error message + */ + QString errorMessage() { QString r = error; error = QString::null; return r; } + + +/** + * User(s). + * + * If the user is the root user, the cron vector will have a member for + * each user of the host plus one for the system crontab. + * + * If the user is a non-root user, there will be only one member in the + * cron vector. + */ + std::vector<CTCron*> cron; + +private: + +/** + * Copy construction not allowed. + */ + CTHost(const CTHost& source); + +/** + * Assignment not allowed + */ + void operator = (const CTHost& source); + +/** + * Factory create a cron table. Appends to the end of cron. + */ + CTCron* createCTCron(bool _syscron = false, std::string _login = ""); + CTCron* createCTCron(const struct passwd *); + + QString error; +}; + +typedef std::vector<CTCron*>::iterator CTCronIterator; + +#endif // CTHOST_H diff --git a/kcron/cthour.h b/kcron/cthour.h new file mode 100644 index 0000000..702c410 --- /dev/null +++ b/kcron/cthour.h @@ -0,0 +1,50 @@ +/*************************************************************************** + * CT Hour Header * + * -------------------------------------------------------------------- * + * Copyright (C) 1999, Gary Meyer <gary@meyer.net> * + * -------------------------------------------------------------------- * + * 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. * + ***************************************************************************/ + +#ifndef CTHOUR_H +#define CTHOUR_H + +// Do not introduce any Qt or KDE dependencies into the "CT"-prefixed classes. +// I want to be able to reuse these classes with another GUI toolkit. -GM 11/99 + +#include "ctunit.h" +#include <string> + +/** + * Scheduled task hours. + */ +class CTHour : public CTUnit<0,23> +{ +public: + +/** + * Constructs from a tokenized string. + */ + CTHour(const string &tokStr = "") : CTUnit<0,23>(tokStr) { }; + +/** + * Default copy constructor. + */ + // CTHour(const CTHour& source); + +/** + * Default assignment operator + */ + // void operator = (const CTHour& source); + +/** + * Default destructor. + */ + // ~CTHour(); + +}; + +#endif // CTHOUR_H diff --git a/kcron/cti18n.h b/kcron/cti18n.h new file mode 100644 index 0000000..e3a1757 --- /dev/null +++ b/kcron/cti18n.h @@ -0,0 +1,27 @@ +/*************************************************************************** + * CT Internationalization Header * + * -------------------------------------------------------------------- * + * Copyright (C) 1999, Gary Meyer <gary@meyer.net> * + * -------------------------------------------------------------------- * + * 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. * + ***************************************************************************/ + +#ifndef CTI18N_H +#define CTI18N_H + +// Do not introduce any Qt or KDE dependencies into the "CT"-prefixed classes. +// I want to be able to reuse these classes with another GUI toolkit. -GM 11/99 +// +// Note: I do make an exception to the above rule for this file, as it is +// necessary to support internationalization. +// +// Regardless, please don't introduce any other Qt or KDE dependencies here. +// -GM 11/99 + +#include <klocale.h> +#include <kapplication.h> + +#endif // CTI18N_H diff --git a/kcron/ctminute.h b/kcron/ctminute.h new file mode 100644 index 0000000..6d93e08 --- /dev/null +++ b/kcron/ctminute.h @@ -0,0 +1,50 @@ +/*************************************************************************** + * CT Minute Header * + * -------------------------------------------------------------------- * + * Copyright (C) 1999, Gary Meyer <gary@meyer.net> * + * -------------------------------------------------------------------- * + * 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. * + ***************************************************************************/ + +#ifndef CTMINUTE_H +#define CTMINUTE_H + +// Do not introduce any Qt or KDE dependencies into the "CT"-prefixed classes. +// I want to be able to reuse these classes with another GUI toolkit. -GM 11/99 + +#include "ctunit.h" +#include <string> + +/** + * Scheduled task minutes. + */ +class CTMinute : public CTUnit<0,59> +{ +public: + +/** + * Constructs from a tokenized string. + */ + CTMinute(const string &tokStr = "") : CTUnit<0,59>(tokStr) { }; + +/** + * Default copy constructor. + */ + // CTMinute(const CTMinute& source); + +/** + * Default assignment operator + */ + // void operator = (const CTMinute& source); + +/** + * Default destructor. + */ + // ~CTMinute(); + +}; + +#endif // CTMINUTE_H diff --git a/kcron/ctmonth.cpp b/kcron/ctmonth.cpp new file mode 100644 index 0000000..b66cd39 --- /dev/null +++ b/kcron/ctmonth.cpp @@ -0,0 +1,62 @@ +/*************************************************************************** + * CT Month Implementation * + * -------------------------------------------------------------------- * + * Copyright (C) 1999, Gary Meyer <gary@meyer.net> * + * -------------------------------------------------------------------- * + * 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. * + ***************************************************************************/ + +// Do not introduce any Qt or KDE dependencies into the "CT"-prefixed classes. +// I want to be able to reuse these classes with another GUI toolkit. -GM 11/99 + +#include "ctmonth.h" +#include "cti18n.h" + +string CTMonth::shortName[13] = +{ + "", "", "", "", "", "", "", "", "", "", "", "", "", +}; + +CTMonth::CTMonth(const string& tokStr) : + CTUnit<1,12>(tokStr) +{ +} + +string CTMonth::describe () const +{ + initializeNames(); + return (count() == 12) ? + (const char*)i18n("every month ").local8Bit() : + CTUnit<1,12>::describe(shortName); +} + +string CTMonth::getName(const int ndx) +{ + initializeNames(); + return shortName[ndx]; +} + +void CTMonth::initializeNames() +{ + if (shortName[1].empty()) + { + const string shortMonthName[13] = + { + "", + (const char*)i18n("January").local8Bit(), (const char*)i18n("February").local8Bit(), + (const char*)i18n("March").local8Bit(), (const char*)i18n("April").local8Bit(), + (const char*)i18n("May long","May").local8Bit(), (const char*)i18n("June").local8Bit(), + (const char*)i18n("July").local8Bit(), (const char*)i18n("August").local8Bit(), + (const char*)i18n("September").local8Bit(), (const char*)i18n("October").local8Bit(), + (const char*)i18n("November").local8Bit(), (const char*)i18n("December").local8Bit() + }; + + for (int i = 1; i <= 12; i++) + { + shortName[i] = shortMonthName[i]; + } + } +} diff --git a/kcron/ctmonth.h b/kcron/ctmonth.h new file mode 100644 index 0000000..f7aa8af --- /dev/null +++ b/kcron/ctmonth.h @@ -0,0 +1,63 @@ +/*************************************************************************** + * CT Month Header * + * -------------------------------------------------------------------- * + * Copyright (C) 1999, Gary Meyer <gary@meyer.net> * + * -------------------------------------------------------------------- * + * 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. * + ***************************************************************************/ + +#ifndef CTMONTH_H +#define CTMONTH_H + +// Do not introduce any Qt or KDE dependencies into the "CT"-prefixed classes. +// I want to be able to reuse these classes with another GUI toolkit. -GM 11/99 + +#include "ctunit.h" +#include <string> + +/** + * Scheduled task months. + */ +class CTMonth : public CTUnit<1,12> +{ +public: + +/** + * Constructs from a tokenized string. + */ + CTMonth(const string& tokStr = ""); + +/** + * Default copy constructor. + */ + // CTMonth(const CTMonth& source); + +/** + * Default assignment operator + */ + // void operator = (const CTMonth& source); + +/** + * Default destructor. + */ + // ~CTMonth(); + +/** + * Get natural language description. + */ + virtual string describe() const; + +/** + * Get month name. + */ + static string getName(const int ndx); + +private: + static void initializeNames(); + static string shortName[13]; +}; + +#endif // CTMONTH_H diff --git a/kcron/cttask.cpp b/kcron/cttask.cpp new file mode 100644 index 0000000..1b7b299 --- /dev/null +++ b/kcron/cttask.cpp @@ -0,0 +1,361 @@ +/*************************************************************************** + * CT Task Implementation * + * -------------------------------------------------------------------- * + * Copyright (C) 1999, Gary Meyer <gary@meyer.net> * + * -------------------------------------------------------------------- * + * 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. * + ***************************************************************************/ + +// Do not introduce any Qt or KDE dependencies into the "CT"-prefixed classes. +// I want to be able to reuse these classes with another GUI toolkit. -GM 11/99 + +#include "cttask.h" + +#include "cti18n.h" +#include <time.h> // tm, strftime() + +CTTask::CTTask(string tokStr, string _comment, bool _syscron) : + syscron(_syscron) +{ + if (tokStr.substr(0,2) == "#\\") + { + tokStr = tokStr.substr(2,tokStr.length() - 2); + enabled = false; + } + else if (tokStr.substr(0,1) == "#") + { + tokStr = tokStr.substr(1,tokStr.length() - 1); + enabled = false; + } + else + enabled = true; + + if (tokStr.substr(0,1) == "-") + { + tokStr = tokStr.substr(1,tokStr.length() - 1); + silent = true; + } + else + { + silent = false; + } + + if (tokStr.substr(0,1) == "@") + { + if (tokStr.substr(1,6) == "reboot") + { + // Dunno what to do with this... + tokStr = "0 0 1 1 *"+tokStr.substr(7,tokStr.length()-1); + } + else if (tokStr.substr(1,6) == "yearly") + { + tokStr = "0 0 1 1 *"+tokStr.substr(7,tokStr.length()-1); + } + else if (tokStr.substr(1,8) == "annually") + { + tokStr = "0 0 1 1 *"+tokStr.substr(9,tokStr.length()-1); + } + else if (tokStr.substr(1,7) == "monthly") + { + tokStr = "0 0 1 * *"+tokStr.substr(8,tokStr.length()-1); + } + else if (tokStr.substr(1,6) == "weekly") + { + tokStr = "0 0 * * 0"+tokStr.substr(7,tokStr.length()-1); + } + else if (tokStr.substr(1,5) == "daily") + { + tokStr = "0 0 * * *"+tokStr.substr(6,tokStr.length()-1); + } + else if (tokStr.substr(1,6) == "hourly") + { + tokStr = "0 * * * *"+tokStr.substr(7,tokStr.length()-1); + } + } + + int spacepos(tokStr.find_first_of(" \t")); + minute.initialize(tokStr.substr(0,spacepos)); + + while(isspace(tokStr[spacepos+1])) spacepos++; + tokStr = tokStr.substr(spacepos+1,tokStr.length()-1); + spacepos = tokStr.find_first_of(" \t"); + hour.initialize(tokStr.substr(0,spacepos)); + + while(isspace(tokStr[spacepos+1])) spacepos++; + tokStr = tokStr.substr(spacepos+1,tokStr.length()-1); + spacepos = tokStr.find_first_of(" \t"); + dayOfMonth.initialize(tokStr.substr(0,spacepos)); + + while(isspace(tokStr[spacepos+1])) spacepos++; + tokStr = tokStr.substr(spacepos+1,tokStr.length()-1); + spacepos = tokStr.find_first_of(" \t"); + month.initialize(tokStr.substr(0,spacepos)); + + while(isspace(tokStr[spacepos+1])) spacepos++; + tokStr = tokStr.substr(spacepos+1,tokStr.length()-1); + spacepos = tokStr.find_first_of(" \t"); + dayOfWeek.initialize(tokStr.substr(0,spacepos)); + + if (syscron) + { + while(isspace(tokStr[spacepos+1])) spacepos++; + tokStr = tokStr.substr(spacepos+1,tokStr.length()-1); + spacepos = tokStr.find_first_of(" \t"); + user = tokStr.substr(0,spacepos); + } + else + user = string(""); + + command = tokStr.substr(spacepos+1,tokStr.length()-1); + // remove leading whitespace + while (command.find_first_of(" \t") == 0) + command = command.substr(1,command.length()-1); + comment = _comment; + + initialUser = user; + initialCommand = command; + initialComment = comment; + initialEnabled = enabled; + initialSilent = silent; +} + +CTTask::CTTask(const CTTask &source) : + month(source.month), + dayOfMonth(source.dayOfMonth), + dayOfWeek(source.dayOfWeek), + hour(source.hour), + minute(source.minute), + user(source.user), + command(source.command), + comment(source.comment), + enabled(source.enabled), + silent(source.silent), + initialUser(""), + initialCommand(""), + initialComment(""), + initialEnabled(true), + initialSilent(false) +{ +} + +void CTTask::operator = (const CTTask& source) +{ + month = source.month; + dayOfMonth = source.dayOfMonth; + dayOfWeek = source.dayOfWeek; + hour = source.hour; + minute = source.minute; + user = source.user; + command = source.command; + comment = source.comment; + enabled = source.enabled; + silent = source.silent; + initialUser = ""; + initialCommand = ""; + initialComment = ""; + initialEnabled = true; + initialSilent = false; + return; +} + +ostream& operator << (ostream& outputStream, const CTTask& task) +{ +// if (task.comment != string("")) + outputStream << "# " << task.comment << "\n"; + + if (!task.enabled) + outputStream << "#\\"; + + if (task.silent) + outputStream << "-"; + + outputStream << task.minute << " "; + outputStream << task.hour << " "; + outputStream << task.dayOfMonth << " "; + outputStream << task.month << " "; + outputStream << task.dayOfWeek << "\t"; + + if (task.user != string("")) + outputStream << task.user << "\t"; + + outputStream << task.command << "\n"; + + return outputStream; +} + +void CTTask::apply() +{ + month.apply(); + dayOfMonth.apply(); + dayOfWeek.apply(); + hour.apply(); + minute.apply(); + initialUser = user; + initialCommand = command; + initialComment = comment; + initialEnabled = enabled; + initialSilent = silent; +} + +void CTTask::cancel() +{ + month.cancel(); + dayOfMonth.cancel(); + dayOfWeek.cancel(); + hour.cancel(); + minute.cancel(); + user = initialUser; + command = initialCommand; + comment = initialComment; + enabled = initialEnabled; + silent = initialSilent; +} + +bool CTTask::dirty() const +{ + return (month.dirty() || dayOfMonth.dirty() || dayOfWeek.dirty() || + hour.dirty() || minute.dirty() || (user != initialUser) || + (command != initialCommand) || (comment != initialComment) || + (enabled != initialEnabled) || (silent != initialSilent)); +} + +string CTTask::describe() const +{ + + // Of the whole program, this method is probably the trickiest. + // + // This method creates the natural language description, such as + // "At 1:00am, every Sun". + // + // First, I declare some strings for holding what can be internationalized. + // Note the tokens such as "MONTHS". Translators should reuse these + // tokens in their translations. See README.translators for more + // information. + // + // Second, I get the descriptions from the component parts such as + // days of the month. + // + // Third, I get hour/minute time combinations. Although a little bit + // awkward, I use the tm struct and strftime from <time.h>. This + // way this code is portable across all Unixes. + // + // Fourth, I know that "every day of the week" and "every day of the + // month" simply makes "every day". + // + // Fifth and finally I do tag substitution to create the natural language + // description. + + string tmFormat((const char *)i18n("%H:%M").local8Bit()); + string DOMFormat((const char *)i18n("Please translator, read the README.translators file in kcron's source code","DAYS_OF_MONTH of MONTHS").local8Bit()); + string DOWFormat((const char *)i18n("Really, read that file","every DAYS_OF_WEEK").local8Bit()); + string dateFormat((const char *)i18n("DOM_FORMAT as well as DOW_FORMAT").local8Bit()); + string timeFormat((const char *)i18n("At TIME").local8Bit()); + string format((const char *)i18n("TIME_FORMAT, DATE_FORMAT").local8Bit()); + + // Get natural language description of day of month, + // month name, and day of week. + + string DOMDesc(dayOfMonth.describe()); + string monthDesc(month.describe()); + string DOWDesc(dayOfWeek.describe()); + + // Create time description. + + int total(minute.count()*hour.count()); + + string timeDesc(""); + int count(0); + + for (int h = 0; h <= 23; h++) + if (hour.get(h)) + for (int m = 0; m <= 59; m++) + if (minute.get(m)) + { + tm time; + time.tm_sec = 0; + time.tm_min = m; + time.tm_hour = h; + time.tm_mday = 0; + time.tm_mon = 0; + time.tm_year = 0; + time.tm_wday = 0; + time.tm_yday = 0; + time.tm_isdst= 0; + + char tmp[12]; + strftime(tmp, 12, tmFormat.c_str(), &time); + string tmpStr = tmp; + + // remove leading space + if (tmpStr.substr(0,1) == " ") + tmpStr = tmpStr.substr(1,tmpStr.length()-1); + + timeDesc += tmpStr; + count++; + switch (total - count) + { + case 0: break; + case 1: if (total > 2) + timeDesc += (const char *)i18n(", and ").local8Bit(); + else + timeDesc += (const char *)i18n(" and ").local8Bit(); + break; + default: timeDesc += (const char*)i18n(", ").local8Bit(); + } + } + + // "* * *" means truly every day. + // Note: Languages may use different phrases to indicate + // every day of month versus every day of week. + + if ((dayOfMonth.count() == 31) && + (dayOfWeek.count() == 7)) + dateFormat = (const char *)i18n("every day ").local8Bit(); + else + { + // Day of month not specified, so use day of week. + if (dayOfMonth.count() == 31) + dateFormat = "DOW_FORMAT"; + // Day of week not specified, so use day of month. + if (dayOfWeek.count() == 7) + dateFormat = "DOM_FORMAT"; + } + + // Replace tags to build natural language description. + + int pos(0); + + if ((pos = DOMFormat.find("DAYS_OF_MONTH")) > -1) + DOMFormat.replace(pos,13,DOMDesc); + + if ((pos = DOMFormat.find("MONTHS")) > -1) + DOMFormat.replace(pos,6,monthDesc); + + if ((pos = DOWFormat.find("DAYS_OF_WEEK")) > -1) + DOWFormat.replace(pos,12,DOWDesc); + + if ((pos = dateFormat.find("DOM_FORMAT")) > -1) + dateFormat.replace(pos,10,DOMFormat); + + if ((pos = dateFormat.find("DOW_FORMAT")) > -1) + dateFormat.replace(pos,10,DOWFormat); + + if ((pos = timeFormat.find("TIME")) > -1) + timeFormat.replace(pos,4,timeDesc); + + if ((pos = format.find("DATE_FORMAT")) > -1) + format.replace(pos,11,dateFormat); + + if ((pos = format.find("TIME_FORMAT")) > -1) + format.replace(pos,11,timeFormat); + + return format; +} + +bool CTTask::system() const +{ + return syscron; +} diff --git a/kcron/cttask.h b/kcron/cttask.h new file mode 100644 index 0000000..3665c61 --- /dev/null +++ b/kcron/cttask.h @@ -0,0 +1,104 @@ +/*************************************************************************** + * CT Task Header * + * -------------------------------------------------------------------- * + * Copyright (C) 1999, Gary Meyer <gary@meyer.net> * + * -------------------------------------------------------------------- * + * 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. * + ***************************************************************************/ + +#ifndef CTTASK_H +#define CTTASK_H + +// Do not introduce any Qt or KDE dependencies into the "CT"-prefixed classes. +// I want to be able to reuse these classes with another GUI toolkit. -GM 11/99 + +#include <string> + +#include "ctmonth.h" +#include "ctdom.h" +#include "ctdow.h" +#include "cthour.h" +#include "ctminute.h" + +/** + * A scheduled task (encapsulation of crontab entry). Encapsulates + * parsing, tokenization, and natural language description. + */ +class CTTask +{ +public: + +/** + * Constructs scheduled task from crontab format string. + */ + CTTask(string tokStr = "", string _comment = "", bool syscron = false); + +/** + * Copy constructor. + */ + CTTask(const CTTask& source); + +/** + * Assignment operator. + */ + void operator = (const CTTask& source); + +/** + * Default constructor. + */ + // ~CTTask(); + +/** + * Tokenizes scheduled task to crontab format. + */ + friend ostream& operator << (ostream& outputStream, const CTTask& task); + +/** + * Mark changes as applied. + */ + void apply(); + +/** + * Cancel changes. + */ + void cancel(); + +/** + * Indicates whether or not the task has been modified. + */ + bool dirty() const; + +/** + * Returns natural language description of the task's schedule. + */ + string describe() const; + +/** + * Indicates whether or not the task belongs to the system crontab. + */ + bool system() const; + + CTMonth month; + CTDayOfMonth dayOfMonth; + CTDayOfWeek dayOfWeek; + CTHour hour; + CTMinute minute; + string user; + string command; + string comment; + bool enabled; + bool silent; + +private: + bool syscron; + string initialUser; + string initialCommand; + string initialComment; + bool initialEnabled; + bool initialSilent; +}; + +#endif // CTTASK_H diff --git a/kcron/ctunit.cpp b/kcron/ctunit.cpp new file mode 100644 index 0000000..0532131 --- /dev/null +++ b/kcron/ctunit.cpp @@ -0,0 +1,319 @@ +/*************************************************************************** + * CT Unit of Time Interval Implementation * + * -------------------------------------------------------------------- * + * Copyright (C) 1999, Gary Meyer <gary@meyer.net> * + * -------------------------------------------------------------------- * + * 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. * + ***************************************************************************/ + +// Do not introduce any Qt or KDE dependencies into the "CT"-prefixed classes. +// I want to be able to reuse these classes with another GUI toolkit. -GM 11/99 + +#include "cti18n.h" +#include <vector> +#include <string> +#include <stdio.h> // sprintf +#include <ctype.h> // tolower +#include <stdlib.h> + +using namespace std; + +template<int min, int max> +CTUnit<min, max>::CTUnit(const string &tokStr) +{ + initialize(tokStr); +} + +template<int min, int max> +CTUnit<min, max>::CTUnit(const CTUnit& source) +{ + for (int i = 0; i <= max; i++) + { + initialEnabled[i] = 0; + enabled[i] = source.enabled[i]; + } + initialTokStr = ""; + isDirty = true; +} + +template<int min, int max> +CTUnit<min, max>::~CTUnit() +{ +} + +template<int min, int max> +void CTUnit<min, max>::operator = (const CTUnit<min,max>& unit) +{ + for (int i = 0; i <= max; i++) + enabled[i] = unit.enabled[i]; + isDirty = true; + return; +} + +template<int min, int max> +void CTUnit<min, max>::initialize(const string &tokStr) +{ + for (int i = 0; i <= max; i++) + enabled[i] = 0; + + parse(tokStr); + + for (int i = min; i <= max; i++) + initialEnabled[i] = enabled[i]; + + initialTokStr = tokStr; + isDirty = false; + + return; +} + +template<int min, int max> +void CTUnit<min, max>::parse(string tokStr) +{ + // subelement is that which is between commas + string subelement; + int commapos, slashpos, dashpos; + int beginat, endat, step; + + // loop through each subelement + tokStr += ","; + while ((commapos = tokStr.find(",")) > 0) + { + subelement = tokStr.substr(0,commapos); + + // find "/" to determine step + slashpos = subelement.find("/"); + if (slashpos == -1) + { + step = 1; + slashpos = subelement.length(); + } + else + { + step = fieldToValue(subelement.substr(slashpos+1, + subelement.length()-slashpos-1)); + if (step < 1) + step = 1; + } + + // find "=" to determine range + dashpos = subelement.find("-"); + if (dashpos == -1) + { + // deal with "*" + if (subelement.substr(0,slashpos) == "*") + { + beginat = min; + endat = max; + } + else + { + beginat = fieldToValue(subelement.substr(0,slashpos)); + endat = beginat; + } + } + else + { + beginat = fieldToValue(subelement.substr(0,dashpos)); + endat = fieldToValue(subelement.substr(dashpos+1,slashpos-dashpos-1)); + } + + // ignore out of range + if (beginat < 0) + beginat = 0; + if (endat > max) + endat = max; + + // setup enabled + for (int i = beginat; i <= endat; i+=step) + enabled[i] = 1; + + tokStr = tokStr.substr(commapos+1, tokStr.length()-commapos-1); + } + return; +} + +template<int min, int max> +string CTUnit<min, max>::tokenize() const +{ + if (!isDirty) + { + return initialTokStr; + } + else + { + int total(count()); + int count(0); + int num(min); + string tmpStr; + + while (num <= max) + { + if (enabled[num]) + { + char cnum[3]; + sprintf(cnum, "%u", num); + tmpStr += cnum; + if (++count < total) + tmpStr += ","; + } + num++; + } + if (count == (max - min + 1)) + tmpStr = "*"; + return tmpStr; + } +} + +template<int min, int max> +string CTUnit<min, max>::describe(const string *label) const +{ + int total(count()); + int count(0); + string tmpStr; + for (int i = min; i <= max; i++) + { + if (enabled[i]) + { + tmpStr += label[i]; + count++; + switch (total - count) + { + case 0: break; + case 1: if (total > 2) tmpStr += (const char *)i18n(",").local8Bit(); + tmpStr += (const char *)i18n(" and ").local8Bit(); + break; + default: tmpStr += (const char *)i18n(", ").local8Bit(); + break; + } + } + } + return tmpStr; +} + +template<int min, int max> +int CTUnit<min, max>::begin() +{ + return min; +} + +template<int min, int max> +int CTUnit<min, max>::end() +{ + return max; +} + +template<int min, int max> +bool CTUnit<min, max>::get(int pos) const +{ + return enabled[pos]; +} + +template<int min, int max> +void CTUnit<min, max>::set(int pos, bool value) +{ + enabled[pos] = value; + isDirty = true; + return; +} + +template<int min, int max> +void CTUnit<min, max>::enable(int pos) +{ + enabled[pos] = true; + isDirty = true; + return; +} + +template<int min, int max> +void CTUnit<min, max>::disable(int pos) +{ + enabled[pos] = false; + isDirty = true; + return; +} + +template<int min, int max> +bool CTUnit<min, max>::dirty() const +{ + return isDirty; +} + +template<int min, int max> +int CTUnit<min, max>::count() const +{ + int total(0); + for (int i = min; i <= max; i++) + total += (enabled[i] == true); + return total; +} + +template<int min, int max> +void CTUnit<min, max>::apply() +{ + initialTokStr = tokenize(); + for (int i = min; i <= max; i++) + initialEnabled[i] = enabled[i]; + isDirty = false; + return; +} + +template<int min, int max> +void CTUnit<min, max>::cancel() +{ + for (int i = min; i <= max; i++) + enabled[i] = initialEnabled[i]; + isDirty = false; + return; +} + +template<int min, int max> +int CTUnit<min, max>::fieldToValue(string entry) const +{ + // GNU C++ STL has no String::toLower() so we have to lower + // by hand. + + string lower(""); + int length = entry.length(); + for (int i = 0; i < length; i++) + lower += tolower(*(entry.substr(i, 1).c_str())); + + // check for days + string days[7] = + { + "sun", "mon", "tue", "wed", "thu", "fri", "sat" + }; + + for (int day = 0; day < 7; day++) + { + if (lower == days[day]) + { + char cnum[3]; + sprintf(cnum, "%u", day); + entry = cnum; + } + } + + // check for months + string months[13] = + { + "", + "jan", "feb", "mar", "apr", "may", "jun", + "jul", "aug", "sep", "oct", "nov", "dec" + }; + + for (int month = 1; month < 13; month++) + { + if (lower == months[month]) + { + char cnum[3]; + sprintf(cnum, "%u", month); + entry = cnum; + } + } + + return atoi(entry.c_str()); +} diff --git a/kcron/ctunit.h b/kcron/ctunit.h new file mode 100644 index 0000000..871a274 --- /dev/null +++ b/kcron/ctunit.h @@ -0,0 +1,158 @@ +/*************************************************************************** + * CT Unit of Time Interval Header * + * -------------------------------------------------------------------- * + * Copyright (C) 1999, Gary Meyer <gary@meyer.net> * + * -------------------------------------------------------------------- * + * 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. * + ***************************************************************************/ + +#ifndef CTUNIT_H +#define CTUNIT_H + +// Do not introduce any Qt or KDE dependencies into the "CT"-prefixed classes. +// I want to be able to reuse these classes with another GUI toolkit. -GM 11/99 + +#include <string> +#include <iostream> + +/** + * A cron table unit parser and tokenizer. + * Parses/tokenizes unit such as "0-3,5,6,10-30/5" + * Also provides default natural language description. + */ +template<int min, int max> class CTUnit +{ +public: + +/** + * Constant indicating short format. + */ + static const bool shortFormat = 0; + +/** + * Constant indicating long format. + */ + static const bool longFormat = 1; + +/** + * Initialize including parsing and saving initial image. + */ + CTUnit(const std::string &tokStr = ""); + +/** + * Base initial image as empty and copy enabled intervals. + */ + CTUnit(const CTUnit& source); + +/** + * Destructor. + */ + virtual ~CTUnit(); + +/** + * Copy enabled intervals. + */ + void operator = (const CTUnit<min,max>& unit); + +/** + * Returns tokenization to output stream. + */ + friend std::ostream& operator << (std::ostream& outStr, const CTUnit<min,max>& unit) + { + if (unit.count() == (max - min + 1)) + outStr << "*"; + else + outStr << ((const CTUnit<min, max>) unit).tokenize(); + return outStr; + }; + +/** + * Parses unit such as "0-3,5,6,10-30/5". + * And initialize array of enabled intervals. + */ + void initialize(const std::string &tokStr = ""); + +/** + * Parses unit such as "0-3,5,6,10-30/5". + * Does not initialize array of enabled intervals. + */ + void parse(std::string tokStr = ""); + +/** + * Tokenizes unit into string such as + * "0,1,2,3,5,6,10,15,20,25,30". + */ + std::string tokenize() const; + +/** + * Get default natural language description. + */ + virtual std::string describe(const std::string *label) const; + +/** + * Lower bound. + */ + int begin(); + +/** + * Upper bound. + */ + int end(); + +/** + * Accessor. + */ + bool get(int pos) const; + +/** + * Mutator. + */ + void set(int pos, bool value); + +/** + * Enable. + */ + void enable(int pos); + +/** + * Disable. + */ + void disable(int pos); + +/** + * Indicates whether enabled intervals have been modified. + */ + bool dirty() const; + +/** + * Total count of enabled intervals. + */ + int count() const; + +/** + * Mark changes as applied. + */ + void apply(); + +/** + * Mark cancel changes and revert to initial or last applied + * image. + */ + void cancel(); + +private: + + int fieldToValue(std::string entry) const; + bool isDirty; + bool enabled[max+1]; + bool initialEnabled[max+1]; + std::string initialTokStr; + +}; + +#include "ctunit.cpp" + +#endif // CTUNIT_H diff --git a/kcron/ctvariable.cpp b/kcron/ctvariable.cpp new file mode 100644 index 0000000..f736c76 --- /dev/null +++ b/kcron/ctvariable.cpp @@ -0,0 +1,101 @@ +/*************************************************************************** + * CT Environment Variable Implementation * + * -------------------------------------------------------------------- * + * Copyright (C) 1999, Gary Meyer <gary@meyer.net> * + * -------------------------------------------------------------------- * + * 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. * + ***************************************************************************/ + +// Do not introduce any Qt or KDE dependencies into the "CT"-prefixed classes. +// I want to be able to reuse these classes with another GUI toolkit. -GM 11/99 + +#include "ctvariable.h" + +using namespace std; + +CTVariable::CTVariable(string tokStr, string _comment) +{ + if (tokStr.substr(0,2) == "#\\") + { + tokStr = tokStr.substr(2,tokStr.length() - 2); + enabled = false; + } + else + enabled = true; + + int spacepos(0); + + spacepos = tokStr.find_first_of(" ="); + variable = tokStr.substr(0,spacepos); + + value = tokStr.substr(spacepos+1,tokStr.length()-spacepos-1); + comment = _comment; + + initialVariable = variable; + initialValue = value; + initialComment = comment; + initialEnabled = enabled; +} + +CTVariable::CTVariable(const CTVariable &source) : + variable(source.variable), + value(source.value), + comment(source.comment), + enabled(source.enabled), + initialVariable(""), + initialValue(""), + initialComment(""), + initialEnabled(true) +{ +} + +void CTVariable::operator = (const CTVariable& source) +{ + variable = source.variable; + value = source.value; + comment = source.comment; + enabled = source.enabled; + initialVariable = ""; + initialValue = ""; + initialComment = ""; + initialEnabled = true; + return; +} + +ostream& operator << (ostream& outputStream, const CTVariable& source) +{ + if (source.comment != string("")) + outputStream << "# " << source.comment << "\n"; + + if (!source.enabled) + outputStream << "#\\"; + + outputStream << source.variable << "=" << source.value << "\n"; + + return outputStream; +} + +void CTVariable::apply() +{ + initialVariable = variable; + initialValue = value; + initialComment = comment; + initialEnabled = enabled; +} + +void CTVariable::cancel() +{ + variable = initialVariable; + value = initialValue; + comment = initialComment; + enabled = initialEnabled; +} + +bool CTVariable::dirty() const +{ + return ((variable != initialVariable) || (value != initialValue) || + (comment != initialComment) || (enabled != initialEnabled)); +} diff --git a/kcron/ctvariable.h b/kcron/ctvariable.h new file mode 100644 index 0000000..3f20600 --- /dev/null +++ b/kcron/ctvariable.h @@ -0,0 +1,82 @@ +/*************************************************************************** + * CT Environment Variable Header * + * -------------------------------------------------------------------- * + * Copyright (C) 1999, Gary Meyer <gary@meyer.net> * + * -------------------------------------------------------------------- * + * 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. * + ***************************************************************************/ + +#ifndef CTVARIABLE_H +#define CTVARIABLE_H + +// Do not introduce any Qt or KDE dependencies into the "CT"-prefixed classes. +// I want to be able to reuse these classes with another GUI toolkit. -GM 11/99 + +#include <string> +#include <fstream> + +/** + * An environment variable (encapsulation of crontab environment variable + * entry). Encapsulates parsing and tokenization. + */ +class CTVariable +{ +public: + +/** + * Constructs environment variable from crontab format string. + */ + CTVariable(std::string tokStr = "", std::string _comment = ""); + +/** + * Copy constructor. + */ + CTVariable(const CTVariable& source); + +/** + * Assignment operator. + */ + void operator = (const CTVariable& source); + +/** + * Default destructor. + */ + // ~CTVariable(); + +/** + * Tokenizes environment variable to crontab format. + */ + friend std::ostream& operator << (std::ostream& outputStream, const CTVariable& task); + +/** + * Mark changes as applied. + */ + void apply(); + +/** + * Cancel changes. + */ + void cancel(); + +/** + * Indicates whether or not the environment variable has been modified. + */ + bool dirty() const; + + std::string variable; + std::string value; + std::string comment; + bool enabled; + +private: + std::string initialVariable; + std::string initialValue; + std::string initialComment; + bool initialEnabled; + +}; + +#endif // CTVARIABLE_H diff --git a/kcron/hi16-app-kcron.png b/kcron/hi16-app-kcron.png Binary files differnew file mode 100644 index 0000000..d7c1b21 --- /dev/null +++ b/kcron/hi16-app-kcron.png diff --git a/kcron/hi22-app-kcron.png b/kcron/hi22-app-kcron.png Binary files differnew file mode 100644 index 0000000..f97e3bc --- /dev/null +++ b/kcron/hi22-app-kcron.png diff --git a/kcron/hi32-app-kcron.png b/kcron/hi32-app-kcron.png Binary files differnew file mode 100644 index 0000000..1cfe6b7 --- /dev/null +++ b/kcron/hi32-app-kcron.png diff --git a/kcron/kcron.desktop b/kcron/kcron.desktop new file mode 100644 index 0000000..af1e675 --- /dev/null +++ b/kcron/kcron.desktop @@ -0,0 +1,94 @@ +[Desktop Entry] +Type=Application +Exec=kcron %i %m -caption "%c" +Icon=kcron +DocPath=kcron/index.html +Name=KCron +Name[af]= kcron +Name[ar]=برنامج KCron +Name[bn]=কে-ক্রন +Name[eo]=Taskoplanilo +Name[hi]=के-क्रॉन +Name[mn]=КДЕ Крон +Name[ne]=केडीई क्रोन +Name[sv]=Kcron +Name[ta]=கேக்ரொன் +Name[tg]=Kрон +Name[th]=ตารางงาน - K +GenericName=Task Scheduler +GenericName[af]=Opdrag Skeduleerder +GenericName[ar]=مجدول المهام +GenericName[az]=Vəzifə Zamanlayıcısı +GenericName[bg]=Диспечер на задачи +GenericName[bn]=কর্ম সূচী নির্ধারনকারী +GenericName[br]=Steuñvaer dleadoù +GenericName[bs]=Zakazivanje zadataka +GenericName[ca]=Planificador de tasques +GenericName[cs]=Plánovač úloh +GenericName[cy]=Trefnlennydd Tasgau +GenericName[da]=Opgaveskemalægger +GenericName[de]=Aufgabenplaner +GenericName[el]=Προγραμματισμός εργασιών +GenericName[eo]=Planas taskojn por lanĉo je certaj tempoj +GenericName[es]=Planificador de tareas +GenericName[et]=Crontabi haldamine +GenericName[eu]=Lan kudeatzailea +GenericName[fa]=زمانبند تکلیف +GenericName[fi]=Tehtävien ajastus +GenericName[fo]=Uppgávuplanleggjari +GenericName[fr]=Planificateur de tâches +GenericName[ga]=Sceidealóir na dTascanna +GenericName[gl]=Programador de Tarefas +GenericName[he]=מתזמן משימות +GenericName[hi]=टास्क शेड्यूलर +GenericName[hr]=Planer zadataka +GenericName[hu]=Feladatütemező +GenericName[is]=Verkefnastjóri +GenericName[it]=Pianificatore di operazioni +GenericName[ja]=タスクスケジューラ +GenericName[ka]=ამოცანათა დამგეგმავი +GenericName[kk]=Тапсырма жоспарлағыш +GenericName[km]=កម្មវិធីកំណត់ពេលភារកិច្ច +GenericName[ko]=작업 스케줄러 +GenericName[lt]=Užduočių planuotojas +GenericName[lv]=Uzdevumu Plānotājs +GenericName[mk]=Распоредувач на задачи +GenericName[mn]=Ажлын Төлөвлөгч +GenericName[ms]=Penjadual Tugas +GenericName[mt]=Skeda ta' Xogħol +GenericName[nb]=Oppgavebehandler +GenericName[nds]=Opgavenpleger +GenericName[ne]=कार्य अनुसूचक +GenericName[nl]=Takenplanner +GenericName[nn]=Oppgåveplanleggjar +GenericName[pa]=ਕੰਮ ਨਿਯਮਕਾਰ +GenericName[pl]=Harmonogram zadań +GenericName[pt]=Escalonador de Tarefas +GenericName[pt_BR]=Agendador de Tarefas +GenericName[ro]=Planificator de procese +GenericName[ru]=Планировщик задач +GenericName[se]=Bargoplánejeaddji +GenericName[sk]=Plánovač úloh +GenericName[sl]=Razporejevalnik opravil +GenericName[sr]=Организатор задатака +GenericName[sr@Latn]=Organizator zadataka +GenericName[sv]=Jobbschemaläggare +GenericName[ta]=பணி அமைப்பான் +GenericName[tg]=Нақшаи Масъала +GenericName[th]=ตารางงาน +GenericName[tr]=Görev Zamanlayıcı +GenericName[uk]=Планувальник задач +GenericName[uz]=Vazifani jadval boʻyicha bajargich +GenericName[uz@cyrillic]=Вазифани жадвал бўйича бажаргич +GenericName[ven]=Muvhekanyi wa Mushumo +GenericName[vi]=Bộ lập lịch công việc +GenericName[wa]=Tiestires C +GenericName[xh]=Umcwangcisi Womsebenzi +GenericName[zh_CN]=任务调度程序 +GenericName[zh_HK]=工作排程器 +GenericName[zh_TW]=工作排程器 +GenericName[zu]=Umgcini sikhathi Somsebenzi +Terminal=false +X-KDE-StartupNotify=true +X-DCOP-ServiceType=Multi +Categories=Qt;KDE;System; diff --git a/kcron/kcron.lsm b/kcron/kcron.lsm new file mode 100644 index 0000000..87f9688 --- /dev/null +++ b/kcron/kcron.lsm @@ -0,0 +1,14 @@ +Begin3 +Title: KCron +Version: 1.0 +Entered-date: 1 September 1999 +Description: KDE Task Scheduler +Keywords: KDE, X11, Qt +Author: Gary Meyer <gary@meyer.net> Robert Berry <rjmber@ntlworld.com> +Maintained-by: Gary Meyer <gary@meyer.net> +Primary-site: +Home-page: http://gary.meyer.net/ +Original-site: +Platform: Linux and other Unices, needs Qt, KDE, and cron +Copying-policy: GNU Public License +End diff --git a/kcron/kcronui.rc b/kcron/kcronui.rc new file mode 100644 index 0000000..aab97db --- /dev/null +++ b/kcron/kcronui.rc @@ -0,0 +1,54 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui name="kcron" version="1"> +<MenuBar> + <Menu name="edit"> + <Separator/> + <Action name="edit_new"/> + <Action name="edit_modify"/> + <Action name="edit_delete"/> + <Separator/> + <Action name="edit_enable"/> + <Separator/> + <Action name="edit_run"/> + </Menu> + <Menu name="settings"> + <Action name="show_toolbar"/> + <Action name="show_statusbar"/> + </Menu> +</MenuBar> + +<ToolBar name="mainToolBar"> + <Action name="edit_new"/> + <Action name="edit_modify"/> + <Action name="edit_delete"/> +</ToolBar> + +<ActionProperties> + <Action name="edit_new" icon="filenew"/> + <Action name="edit_modify" icon="edit"/> + <Action name="edit_delete" icon="editdelete"/> + <Action name="edit_run" icon="run"/> +</ActionProperties> + +<State name="no_task_selected"> + <Disable> + <Action name="edit_cut"/> + <Action name="edit_copy"/> + <Action name="edit_modify"/> + <Action name="edit_delete"/> + </Disable> +</State> + +<State name="paste_disabled"> + <Disable> + <Action name="edit_paste"/> + </Disable> +</State> + +<State name="runnow_enabled"> + <Enable> + <Action name="edit_run"/> + </Enable> +</State> + +</kpartgui> diff --git a/kcron/ktapp.cpp b/kcron/ktapp.cpp new file mode 100644 index 0000000..76f0e08 --- /dev/null +++ b/kcron/ktapp.cpp @@ -0,0 +1,463 @@ +/*************************************************************************** + * KT application implementation. * + * -------------------------------------------------------------------- * + * Copyright (C) 1999, Gary Meyer <gary@meyer.net> * + * -------------------------------------------------------------------- * + * 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. * + ***************************************************************************/ + +#include "ktapp.h" +#include <kmenubar.h> +#include <kstdaccel.h> +#include <kmessagebox.h> +#include <kconfig.h> +#include <kapplication.h> +#include <klocale.h> // i18n() +#include <kstdaction.h> +#include <kaction.h> +#include <kiconloader.h> +#include <kpopupmenu.h> +#include <kstatusbar.h> + +#include "cthost.h" +#include "ctcron.h" +#include "cttask.h" + +#include "kticon.h" +#include "ktview.h" + + +const int KTApp::statusMessage (1001); + + +KTApp::KTApp() : KMainWindow(0) +{ + config=kapp->config(); + + setIcon(KTIcon::application(true)); + + setCaption(i18n("Task Scheduler")); + + + // Initialize document. + cthost = new CTHost(); + + // Initialize view. + view = new KTView(this); + setCentralWidget(view); + + // Call inits to invoke all other construction parts. + setupActions(); + initStatusBar(); + createGUI(); + view->disableIcons(); + + //Connections + KPopupMenu *editMenu = static_cast<KPopupMenu*>(guiFactory()->container("edit", this)); + KPopupMenu *settingsMenu = static_cast<KPopupMenu*>(guiFactory()->container("settings", this)); + + connect(editMenu,SIGNAL(highlighted(int)),this,SLOT(statusEditCallback(int))); + connect(settingsMenu,SIGNAL(highlighted(int)),this,SLOT(statusSettingsCallback(int))); + // Read options. + readOptions(); +} + +bool KTApp::init() +{ + if (cthost->isError()) + { + KMessageBox::error(this, i18n("The following error occurred while initializing KCron:" + "\n\n%1\n\nKCron will now exit.\n").arg(cthost->errorMessage())); + return false; + } + + // Display greeting screen. + // if there currently are no scheduled tasks... + if (!cthost->root()) + { + int taskCount(0); + + for (CTCronIterator i = (CTCronIterator)cthost->cron.begin(); + i != cthost->cron.end(); i++) + { + for (CTTaskIterator j = (CTTaskIterator)(*i)->task.begin(); + j != (*i)->task.end(); j++) + { + taskCount++; + } + } + + if (taskCount == 0) + { + show(); + KMessageBox::information(this, i18n("You can use this application to schedule programs to run in the background.\nTo schedule a new task now, click on the Tasks folder and select Edit/New from the menu."), i18n("Welcome to the Task Scheduler"), "welcome"); + } + } + return true; +} + +KTApp::~KTApp() +{ + delete view; + delete cthost; +} + +const CTHost& KTApp::getCTHost() const +{ + return *cthost; +} + + +QString KTApp::caption() +{ + QString cap(kapp->caption()); + return cap; +} + +void KTApp::setupActions() +{ + //File Menu + KStdAction::save(this, SLOT(slotFileSave()), actionCollection()); + KStdAction::print(this, SLOT(slotFilePrint()), actionCollection()); + KStdAction::quit(this, SLOT(slotFileQuit()), actionCollection()); + + //Edit menu + KStdAction::cut(this, SLOT(slotEditCut()), actionCollection()); + KStdAction::copy(this, SLOT(slotEditCopy()), actionCollection()); + KStdAction::paste(this, SLOT(slotEditPaste()), actionCollection()); + (void)new KAction(i18n("&New..."), KStdAccel::openNew(), this,SLOT(slotEditNew()),actionCollection(),"edit_new"); + //I don't like this KStdAccel::open() for modifying, but I'm just porting this to xmlui + (void)new KAction(i18n("M&odify..."), KStdAccel::open(), this,SLOT(slotEditModify()),actionCollection(),"edit_modify"); + (void)new KAction(i18n("&Delete"), 0, this,SLOT(slotEditDelete()),actionCollection(),"edit_delete"); + (void)new KAction(i18n("&Enabled"), 0, this,SLOT(slotEditEnable()),actionCollection(),"edit_enable"); + (void)new KAction(i18n("&Run Now"), 0, this,SLOT(slotEditRunNow()),actionCollection(),"edit_run"); + + //Settings menu + (void)new KAction(i18n("Show &Toolbar"), 0, this,SLOT(slotViewToolBar()),actionCollection(),"show_toolbar"); + (void)new KAction(i18n("Show &Statusbar"), 0, this,SLOT(slotViewStatusBar()),actionCollection(),"show_statusbar"); + +} + +void KTApp::initStatusBar() +{ + statusBar()->insertItem(i18n("Ready."), statusMessage, 1); + statusBar()->setItemAlignment(statusMessage, Qt::AlignLeft | Qt::AlignVCenter); +} + +void KTApp::saveOptions() +{ + config->setGroup(QString("General Options")); + config->writeEntry(QString("Geometry"), size()); + config->writeEntry(QString("Show Toolbar"), toolBar()->isVisible()); + config->writeEntry(QString("Show Statusbar"), statusBar()->isVisible()); + config->writeEntry(QString("ToolBarPos"), (int)toolBar()->barPos()); +} + + +void KTApp::readOptions() +{ + config->setGroup(QString("General Options")); + KPopupMenu *settingsMenu = static_cast<KPopupMenu*>(guiFactory()->container("settings", this)); + + // bar status settings + bool bViewToolbar = config->readBoolEntry(QString("Show Toolbar"), true); + settingsMenu->setItemChecked(settingsMenu->idAt(0),bViewToolbar); + if (!bViewToolbar) + toolBar()->hide(); + + bool bViewStatusbar = config->readBoolEntry(QString("Show Statusbar"), true); + settingsMenu->setItemChecked(settingsMenu->idAt(1),bViewStatusbar); + if (!bViewStatusbar) + statusBar()->hide(); + + // bar position settings + KToolBar::BarPosition tool_bar_pos; + tool_bar_pos=(KToolBar::BarPosition) + config->readNumEntry(QString("ToolBarPos"), + KToolBar::Top); + + toolBar()->setBarPos(tool_bar_pos); + + QSize size=config->readSizeEntry(QString("Geometry")); + + // Minimum size is 350 by 250 + + if (size.isEmpty()) + { + size.setWidth(350); + size.setHeight(250); + } + + if (size.width() < 350) + { + size.setWidth(350); + } + if (size.height() < 250) + { + size.setHeight(250); + } + + resize(size); + +} + +bool KTApp::queryClose() +{ + if(cthost->dirty()) + { + KTApp* win = (KTApp*)parent(); + + int retVal = KMessageBox::warningYesNoCancel(win, + i18n("Scheduled tasks have been modified.\nDo you want to save changes?"), + QString::null, + KStdGuiItem::save(), KStdGuiItem::discard() + ); + + switch (retVal) + { + case KMessageBox::Yes: + cthost->apply(); + if (cthost->isError()) + { + KMessageBox::error(win, cthost->errorMessage()); + return false; + } + return true; + break; + case KMessageBox::No: + return true; + break; + case KMessageBox::Cancel: + return false; + break; + default: + return false; + break; + } + } + else + { + return true; + } +} + +bool KTApp::queryExit() +{ + saveOptions(); + return true; +} + +void KTApp::slotFileSave() +{ + slotStatusMsg(i18n("Saving...")); + cthost->apply(); + slotStatusMsg(i18n("Ready.")); + if (cthost->isError()) + { + KMessageBox::error(this, cthost->errorMessage()); + } +} + +void KTApp::slotFilePrint() +{ + slotStatusMsg(i18n("Printing...")); + view->print(); + slotStatusMsg(i18n("Ready.")); +} + +void KTApp::slotFileQuit() +{ + saveOptions(); + close(); +} + +void KTApp::slotEdit(const QPoint& qp) +{ + KPopupMenu *editMenu = static_cast<KPopupMenu*>(guiFactory()->container("edit", this)); + editMenu->exec(qp, 0); +} + +void KTApp::slotEditCut() +{ + slotStatusMsg(i18n("Cutting to clipboard...")); + view->copy(); + view->remove(); + slotStatusMsg(i18n("Ready.")); +} + +void KTApp::slotEditCopy() +{ + slotStatusMsg(i18n("Copying to clipboard...")); + view->copy(); + slotStatusMsg(i18n("Ready.")); +} + +void KTApp::slotEditPaste() +{ + slotStatusMsg(i18n("Pasting from clipboard...")); + view->paste(); + slotStatusMsg(i18n("Ready.")); +} + +void KTApp::slotEditNew() +{ + slotStatusMsg(i18n("Adding new entry...")); + view->create(); + slotStatusMsg(i18n("Ready.")); +} + +void KTApp::slotEditModify() +{ + slotStatusMsg(i18n("Modifying entry...")); + view->edit(); + slotStatusMsg(i18n("Ready.")); +} + +void KTApp::slotEditDelete() +{ + slotStatusMsg(i18n("Deleting entry...")); + view->remove(); + slotStatusMsg(i18n("Ready.")); +} + +void KTApp::slotEditEnable() +{ + KPopupMenu *editMenu = static_cast<KPopupMenu*>(guiFactory()->container("edit", this)); + if (editMenu->isItemChecked(editMenu->idAt(8))) + { + slotStatusMsg(i18n("Disabling entry...")); + view->enable(false); + editMenu->setItemChecked(editMenu->idAt(8), false); + } + else + { + slotStatusMsg(i18n("Enabling entry...")); + view->enable(true); + editMenu->setItemChecked(editMenu->idAt(8), true); + } + slotStatusMsg(i18n("Ready.")); +} + +void KTApp::slotEditRunNow() +{ + slotStatusMsg(i18n("Running command...")); + view->run(); + slotStatusMsg(i18n("Ready.")); +} + +void KTApp::slotViewToolBar() +{ + if(toolBar()->isVisible()) + toolBar()->hide(); + else + toolBar()->show(); + + KPopupMenu *settingsMenu = static_cast<KPopupMenu*>(guiFactory()->container("settings", this)); + settingsMenu->setItemChecked(settingsMenu->idAt(0),toolBar()->isVisible()); + + slotStatusMsg(i18n("Ready.")); +} + +void KTApp::slotViewStatusBar() +{ + if (statusBar()->isVisible()) + statusBar()->hide(); + else + statusBar()->show(); + + KPopupMenu *settingsMenu = static_cast<KPopupMenu*>(guiFactory()->container("settings", this)); + settingsMenu->setItemChecked(settingsMenu->idAt(1),statusBar()->isVisible()); + + slotStatusMsg(i18n("Ready.")); +} + +void KTApp::slotStatusMsg(const QString & text) +{ + statusBar()->clear(); + statusBar()->changeItem(text, statusMessage); + setCaption(i18n("Task Scheduler"), cthost->dirty()); +} + +void KTApp::slotStatusHelpMsg(const QString & text) +{ + statusBar()->message(text, 2000); +} + +void KTApp::statusEditCallback(int id_) +{ + KPopupMenu *editMenu = static_cast<KPopupMenu*>(guiFactory()->container("edit", this)); + int index = editMenu->indexOf(id_); + switch (index) { + case menuEditNew: + slotStatusHelpMsg(i18n("Create a new task or variable.")); + break; + case menuEditModify: + slotStatusHelpMsg(i18n("Edit the selected task or variable.")); + break; + case menuEditDelete: + slotStatusHelpMsg(i18n("Delete the selected task or variable.")); + break; + case menuEditEnabled: + slotStatusHelpMsg(i18n("Enable/disable the selected task or variable.")); + break; + case menuEditRunNow: + slotStatusHelpMsg(i18n("Run the selected task now.")); + break; + + default: + break; + } +} + +void KTApp::statusSettingsCallback(int id_) +{ + KPopupMenu *settingsMenu = static_cast<KPopupMenu*>(guiFactory()->container("settings", this)); + int index = settingsMenu->indexOf(id_); + switch (index) { + case menuSettingsShowToolBar: + slotStatusHelpMsg(i18n("Enable/disable the tool bar.")); + break; + case menuSettingsShowStatusBar: + slotStatusHelpMsg(i18n("Enable/disable the status bar.")); + break; + + default: + break; + } +} + +void KTApp::slotEnableModificationButtons(bool state) +{ + if (state) + stateChanged("no_task_selected", StateReverse); + else + stateChanged("no_task_selected"); + +} + +void KTApp::slotEnablePaste(bool state) +{ + if (state) + stateChanged("paste_disabled", StateReverse); + else + stateChanged("paste_disabled"); +} + +void KTApp::slotEnableRunNow(bool state) +{ + if (state) + stateChanged("runnow_enabled"); + else + stateChanged("runnow_enabled", StateReverse); +} + +void KTApp::slotEnableEnabled(bool state) +{ + KPopupMenu *editMenu = static_cast<KPopupMenu*>(guiFactory()->container("edit", this)); + editMenu->setItemChecked(editMenu->idAt(8),state); +} + +#include "ktapp.moc" diff --git a/kcron/ktapp.h b/kcron/ktapp.h new file mode 100644 index 0000000..c42ad06 --- /dev/null +++ b/kcron/ktapp.h @@ -0,0 +1,267 @@ +/*************************************************************************** + * KT application header. * + * -------------------------------------------------------------------- * + * Copyright (C) 1999, Gary Meyer <gary@meyer.net> * + * -------------------------------------------------------------------- * + * 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. * + ***************************************************************************/ + +#ifndef KTAPP_H +#define KTAPP_H + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <kmainwindow.h> + +class KAction; +class QString; +class KTView; +class CTHost; + +/** + * Application that sets up the main window, reads the config file, + * sets up the menu bar, toolbar, and status bar. Obtains the document + * (here the crontab entries) and give it to the view for display. + * + * Provides main window handling, session management and keyboard + * acceleration. + */ +class KTApp : public KMainWindow +{ + Q_OBJECT + + friend class KTView; + +public: + + // Menu constants + enum editEntries + { + menuEditNew=4, + menuEditModify, + menuEditDelete, + menuEditEnabled=8, + menuEditRunNow=10 + }; + + enum settingsEntries + { + menuSettingsShowToolBar, + menuSettingsShowStatusBar + }; + + static const int statusMessage; + +/** + * Initialize the application. + */ + KTApp(); + +/** + * Quit the application.. + */ + ~KTApp(); + +/** + * Additional init + */ + bool init(); + +/** + * Returns a reference to the document. + */ + const CTHost& getCTHost() const; + +protected: + +/** Called on window close event. Asks the document if it is dirty + * and if so, prompts the user for saving before exiting.. + */ + virtual bool queryClose(); + +/** Called when the last window of the application is going to be + * closed. Saves options. + */ + virtual bool queryExit(); + +public slots: + +/** + * Switch argument for status ar help entries on slot selection. Add your + * ID's help here for toolbars and menubar entries. This + * function is only for the edit menu + */ + void statusEditCallback(int id_); + +/** + * Switch argument for status ar help entries on slot selection. Add your + * ID's help here for toolbars and menubar entries. This + * function is only for the settings menu + */ + void statusSettingsCallback(int id_); + +/** + * Save document. + */ + void slotFileSave(); + +/** + * Print document. + */ + void slotFilePrint(); + +/** + * Close all open windows then quits the application. If queryClose() + * returns false because the user canceled the saveModified() dialog, the + * closing breaks. + */ + void slotFileQuit(); + +/** + * Pop up an edit menu. + */ + void slotEdit(const QPoint& qp); + +/** + * Put the marked objects on the clipboard and remove it from the + * document. + */ + void slotEditCut(); + +/** + * Put the marked objects on the clipboard. + */ + void slotEditCopy(); + +/** + * Paste the object on clipboard into the document + */ + void slotEditPaste(); + +/** + * New. + */ + void slotEditNew(); + +/** + * Modify. + */ + void slotEditModify(); + +/** + * Delete. + */ + void slotEditDelete(); + +/** + * Toggle enabled. + */ + void slotEditEnable(); + +/** + * Run program now. + */ + void slotEditRunNow(); + +/** + * Toggle the toolbar being visible. + */ + void slotViewToolBar(); + +/** + * Toggles the status bar being visible. + */ + void slotViewStatusBar(); + +/** + * Changes the status bar contents for the standard label permanently; + * used to indicate current actions. + */ + void slotStatusMsg(const QString & text); + +/** + * Changes the status message of the whole status bar for two seconds, + * then restores the last status. This is used to display status bar + * messages that give information about actions for toolbar icons and + * menu entries. + */ + void slotStatusHelpMsg(const QString & text); + +/** Enables/disables modification buttons + */ + void slotEnableModificationButtons(bool); + +/** Enables/disables paste button + */ + void slotEnablePaste(bool); + +/** Enables/disables "Run now" + */ + void slotEnableRunNow(bool); + +/** Enables/disables "Activated" + */ + void slotEnableEnabled(bool); + +private: + +/** + * Disabled copy constructor. + */ + KTApp(const KTApp& source); + +/** + * Disabled assignment operator. + */ + void operator = (const KTApp& source); + +/** + * Get application caption. + */ + QString caption(); + +/** + * Initialize actions. + */ + void setupActions(); + +/** + * Initialize status bar. + */ + void initStatusBar(); + +/** + * Read general options again and initialize all variables like the + * geometry. + */ + void readOptions(); + +/** + * Save general options like all bar positions and status as well as the + * geometry to the configuration file. + */ + void saveOptions(); + +/** + * Configuration object of the application. + */ + KConfig* config; + +/** + * Main GUI view/working area. + */ + KTView* view; + +/** + * Document object, here crotab enries. + */ + CTHost* cthost; + +}; + +#endif // KTAPP_H diff --git a/kcron/kticon.cpp b/kcron/kticon.cpp new file mode 100644 index 0000000..eff9f3e --- /dev/null +++ b/kcron/kticon.cpp @@ -0,0 +1,115 @@ +/*************************************************************************** + * KT icons implementation. * + * -------------------------------------------------------------------- * + * Copyright (C) 1999, Gary Meyer <gary@meyer.net> * + * -------------------------------------------------------------------- * + * 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. * + ***************************************************************************/ + +#include "kticon.h" + +#include <qimage.h> + +#include <kglobal.h> +#include <kiconloader.h> + +QPixmap KTIcon::getMiniIcon(const QString& name) +{ + return SmallIcon(name); +} + +QPixmap KTIcon::getIcon(const QString& name) +{ + return BarIcon(name); +} + +QPixmap KTIcon::application(bool mini) +{ + if (mini) + return getMiniIcon("kcron"); + else + return getIcon("kcron"); +} + +QPixmap KTIcon::system(bool mini) +{ + if (mini) + return getMiniIcon("openterm"); + else + return getIcon("openterm"); +} + +QPixmap KTIcon::user(bool mini) +{ + if (mini) + return getMiniIcon("kuser"); + else + return getIcon("kuser"); +} + +QPixmap KTIcon::variables(bool mini) +{ + if (mini) + return getMiniIcon("folder"); + else + return getIcon("folder"); +} + +QPixmap KTIcon::variable(bool mini) +{ + if (mini) + return getMiniIcon("mime_empty"); + else + return getIcon("mime_empty"); +} + +QPixmap KTIcon::mail(bool mini) +{ + if (mini) + return getMiniIcon("mail_generic"); + else + return getIcon("mail_generic"); +} + +QPixmap KTIcon::shell(bool mini) +{ + if (mini) + return getMiniIcon("openterm"); + else + return getIcon("openterm"); +} + +QPixmap KTIcon::home(bool mini) +{ + if (mini) + return getMiniIcon("gohome"); + else + return getIcon("gohome"); +} + +QPixmap KTIcon::path(bool mini) +{ + if (mini) + return getMiniIcon("folder"); + else + return getIcon("folder"); +} + +QPixmap KTIcon::tasks(bool mini) +{ + if (mini) + return getMiniIcon("folder"); + else + return getIcon("folder"); +} + +QPixmap KTIcon::task(bool mini) +{ + if (mini) + return getMiniIcon("gear"); + else + return getIcon("gear"); +} diff --git a/kcron/kticon.h b/kcron/kticon.h new file mode 100644 index 0000000..013f726 --- /dev/null +++ b/kcron/kticon.h @@ -0,0 +1,43 @@ +/*************************************************************************** + * KT icons. * + * -------------------------------------------------------------------- * + * Copyright (C) 1999, Gary Meyer <gary@meyer.net> * + * -------------------------------------------------------------------- * + * 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. * + ***************************************************************************/ + +#ifndef KTICON_H +#define KTICON_H + +#include <qpixmap.h> +#include <qstring.h> + +/** + * Wraps all icons used by the application. + */ + +class KTIcon +{ + +public: + + static QPixmap getMiniIcon(const QString& name); + static QPixmap getIcon(const QString& name); + static QPixmap application(bool mini); + static QPixmap system(bool mini); + static QPixmap user(bool mini); + static QPixmap variables(bool mini); + static QPixmap variable(bool mini); + static QPixmap mail(bool mini); + static QPixmap shell(bool mini); + static QPixmap home(bool mini); + static QPixmap path(bool mini); + static QPixmap tasks(bool mini); + static QPixmap task(bool mini); + +}; + +#endif // KTICON_H diff --git a/kcron/ktlistcron.cpp b/kcron/ktlistcron.cpp new file mode 100644 index 0000000..e2535bb --- /dev/null +++ b/kcron/ktlistcron.cpp @@ -0,0 +1,69 @@ +/*************************************************************************** + * KT list view item cron implementation. * + * -------------------------------------------------------------------- * + * Copyright (C) 1999, Gary Meyer <gary@meyer.net> * + * -------------------------------------------------------------------- * + * 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. * + ***************************************************************************/ + +#include "ktlistcron.h" + +#include <qstring.h> +#include <klocale.h> + +#include "ctcron.h" + +#include "kticon.h" +#include "ktprint.h" + +KTListCron::KTListCron(KTListItem* parent, const char* name, + CTCron* _ctcron) : + KTListItem(parent, name, _ctcron) +{ + refresh(); +} + +KTListCron::KTListCron(QListView* parent, const char* name, + CTCron* _ctcron) : + KTListItem(parent, name, _ctcron) +{ + refresh(); +} + +KTListCron::KTListCron(QListView* parent, CTCron* _ctcron) : + KTListItem(parent, (const char*)0, _ctcron) +{ + refresh(); +} + +void KTListCron::refresh() +{ + setPixmap(0, getCTCron()->login.c_str() == (i18n("(System Crontab)")) ? + KTIcon::system(true) : KTIcon::user(true)); + + QString userName = QString::fromLocal8Bit(getCTCron()->login.c_str()); + + if (getCTCron()->login != getCTCron()->name) + { + userName += QString(" ("); + userName += QString::fromLocal8Bit(getCTCron()->name.c_str()); + userName += QString(")"); + } + setText(0, userName); +} + +void KTListCron::print (KTPrint& printer) const +{ + QString userInfo; + userInfo = QString::fromLocal8Bit(getCTCron()->name.c_str()); + + KTListItem* ktli = (KTListItem*)this->firstChild(); + Q_CHECK_PTR(ktli); + while (ktli) { + ktli->print(printer); + ktli = (KTListItem*)ktli->nextSibling(); + } +} diff --git a/kcron/ktlistcron.h b/kcron/ktlistcron.h new file mode 100644 index 0000000..9fe5fe2 --- /dev/null +++ b/kcron/ktlistcron.h @@ -0,0 +1,55 @@ +/*************************************************************************** + * KT list view item cron header. * + * -------------------------------------------------------------------- * + * Copyright (C) 1999, Gary Meyer <gary@meyer.net> * + * -------------------------------------------------------------------- * + * 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. * + ***************************************************************************/ + +#ifndef KTLISTCRON_H +#define KTLISTCRON_H + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "ktlistitem.h" + +/** + * QListViewItem view of a CTCron. + */ +class KTListCron : public KTListItem +{ +public: + +/** + * Construct tasks or variables folder from branch. + */ + KTListCron(KTListItem* parent, const char* name, CTCron* _ctcron); + +/** + * Construct tasks or variables folder from root. + */ + KTListCron(QListView* parent, const char* name, CTCron* _ctcron); + +/** + * Construct user folder from root. + */ + KTListCron(QListView* parent, CTCron* _ctcron); + +/** + * Refresh. + */ + virtual void refresh(); + +/** + *Print user's crontab + */ + virtual void print(KTPrint &printer) const; + +}; + +#endif // KTLISTCRON_H diff --git a/kcron/ktlistitem.cpp b/kcron/ktlistitem.cpp new file mode 100644 index 0000000..02cd163 --- /dev/null +++ b/kcron/ktlistitem.cpp @@ -0,0 +1,46 @@ +/*************************************************************************** + * KT list view item abstract base class implementation. * + * -------------------------------------------------------------------- * + * Copyright (C) 1999, Gary Meyer <gary@meyer.net> * + * -------------------------------------------------------------------- * + * 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. * + ***************************************************************************/ + +#include "ktlistitem.h" +#include "ktprint.h" + +#include "ctcron.h" + +KTListItem::KTListItem(KTListItem* parent, const char* name, CTCron* _ctcron) : + QListViewItem(parent, name), + ctcron(_ctcron) +{ +} + +KTListItem::KTListItem(QListView* parent, const char* name, CTCron* _ctcron) : + QListViewItem(parent, name), + ctcron(_ctcron) +{ +} + +KTListItem::~KTListItem() +{ +} + +void KTListItem::create() +{ + return; +} + +void KTListItem::edit() +{ + return; +} + +CTCron* KTListItem::getCTCron() const +{ + return ctcron; +} diff --git a/kcron/ktlistitem.h b/kcron/ktlistitem.h new file mode 100644 index 0000000..6d10974 --- /dev/null +++ b/kcron/ktlistitem.h @@ -0,0 +1,81 @@ +/*************************************************************************** + * KT list view item abstract base class. * + * -------------------------------------------------------------------- * + * Copyright (C) 1999, Gary Meyer <gary@meyer.net> * + * -------------------------------------------------------------------- * + * 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. * + ***************************************************************************/ + +#ifndef KTLISTITEM_H +#define KTLISTITEM_H + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <qlistview.h> + +class KTPrint; +class CTCron; + +/** + * An enhanced QListViewItem that ensures all list view items have the + * same interface. + */ +class KTListItem : public QListViewItem +{ +public: + +/** + * Construct a root list view item from a CTCron. + */ + KTListItem(KTListItem* parent, const char* name, CTCron* _ctcron); + +/** + * Construct a non-root list view item from a CTCron. + */ + KTListItem(QListView* parent, const char* name, CTCron* _ctcron); + +/** + * Destructor. + */ + virtual ~KTListItem(); + +/** + * Create. + */ + virtual void create(); + +/** + * Edit. + */ + virtual void edit(); + +/** + * Refresh. + */ + virtual void refresh() = 0; + +/** + * Print. + */ + virtual void print(KTPrint &printer) const =0; + +/** + * Get the user's crontab. + */ + CTCron* getCTCron() const; + +private: + +/** + * User's crontab. + */ + CTCron* ctcron; + +}; + +#endif // KTLISTITEM_H diff --git a/kcron/ktlisttask.cpp b/kcron/ktlisttask.cpp new file mode 100644 index 0000000..b496b77 --- /dev/null +++ b/kcron/ktlisttask.cpp @@ -0,0 +1,70 @@ +/*************************************************************************** + * KT list view item task implementation. * + * -------------------------------------------------------------------- * + * Copyright (C) 1999, Gary Meyer <gary@meyer.net> * + * -------------------------------------------------------------------- * + * 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. * + ***************************************************************************/ + +#include <klocale.h> // i18n() + +#include "cttask.h" + +#include "ktlisttask.h" +#include "kticon.h" +#include "kttask.h" +#include "ktprint.h" + +KTListTask::KTListTask(KTListItem* parent, + CTCron* _ctcron, CTTask* _cttask) : + KTListItem(parent, 0, _ctcron), + cttask(_cttask) + +{ + refresh(); + parent->setOpen(true); +} + +void KTListTask::refresh() +{ + setText(0, QString::fromLocal8Bit(cttask->comment.c_str())); + + if (cttask->enabled) + { + setText(1, QString::fromLocal8Bit(cttask->command.c_str())); + setText(2, QString::fromLocal8Bit(cttask->describe().c_str())); + } + else + { + setText(1, ""); + setText(2, i18n("Disabled")); + } + + setPixmap(0, KTIcon::task(true)); +} + +void KTListTask::print (KTPrint &printer) const +{ + printer.print(QString::fromLocal8Bit(cttask->comment.c_str()), 1, KTPrint::alignTextLeft); + if (cttask->enabled) { + printer.print(QString::fromLocal8Bit(cttask->command.c_str()),2, KTPrint::alignTextCenter); + printer.print(QString::fromLocal8Bit(cttask->describe().c_str()),3, KTPrint::alignTextRight); + } + else + printer.print(i18n("Disabled."), 3, KTPrint::alignTextRight); +} + +void KTListTask::edit() +{ + KTTask(cttask,i18n("Modify Task")).exec(); + refresh(); + parent()->sortChildItems(1, true); +} + +CTTask* KTListTask::getCTTask() const +{ + return cttask; +} diff --git a/kcron/ktlisttask.h b/kcron/ktlisttask.h new file mode 100644 index 0000000..bd8054e --- /dev/null +++ b/kcron/ktlisttask.h @@ -0,0 +1,63 @@ +/*************************************************************************** + * KT list view item task header. * + * -------------------------------------------------------------------- * + * Copyright (C) 1999, Gary Meyer <gary@meyer.net> * + * -------------------------------------------------------------------- * + * 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. * + ***************************************************************************/ + +#ifndef KTLISTTASK_H +#define KTLISTTASK_H + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "ktlistitem.h" + +class CTTask; + +/** + * QListViewItem with a CTTask. + */ +class KTListTask : public KTListItem +{ +public: + +/** + * Initialize the list view item and task. + */ + KTListTask(KTListItem* parent, CTCron* _ctcron, CTTask* _cttask); + +/** + * Refresh from underlying task. + */ + virtual void refresh(); + +/** + * Print task. + */ + virtual void print(KTPrint &printer) const; + +/** + * Edit task. + */ + virtual void edit(); + +/** + * Get the task. + */ + CTTask* getCTTask() const; + +private: + +/** + * Task. + */ + CTTask* cttask; +}; + +#endif // KTLISTTASK_H diff --git a/kcron/ktlisttasks.cpp b/kcron/ktlisttasks.cpp new file mode 100644 index 0000000..e1fc19b --- /dev/null +++ b/kcron/ktlisttasks.cpp @@ -0,0 +1,99 @@ +/*************************************************************************** + * KT list view item tasks implementation. * + * -------------------------------------------------------------------- * + * Copyright (C) 1999, Gary Meyer <gary@meyer.net> * + * -------------------------------------------------------------------- * + * 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. * + ***************************************************************************/ + +#include "ktlisttasks.h" + +#include <qstring.h> + +#include <klocale.h> // i18n() +#include <kglobalsettings.h> + +#include "ctcron.h" +#include "cttask.h" + +#include "kticon.h" +#include "ktlisttask.h" +#include "kttask.h" +#include "ktprint.h" + +KTListTasks::KTListTasks(KTListItem* parent, CTCron* _ctcron) : + KTListItem(parent, 0, _ctcron) +{ + refresh(); +} + +KTListTasks::KTListTasks(QListView* parent, CTCron* _ctcron) : + KTListItem(parent, 0, _ctcron) +{ + refresh(); +} + +QString KTListTasks::getDescription() +{ + return i18n("Tasks"); +} + +void KTListTasks::create() +{ + CTTask* temptask = new CTTask ("", "", getCTCron()->syscron); + KTTask* kttask = new KTTask(temptask,i18n("Edit Task")); + kttask->exec(); + delete kttask; + if (temptask->dirty()) + { + getCTCron()->task.push_back(temptask); + new KTListTask(this, getCTCron(), temptask); // Qt will clean up + } + else + { + delete temptask; + } +} + +void KTListTasks::refresh() +{ + setText(0, getDescription()); + setPixmap(0, KTIcon::tasks(true)); +} + +void KTListTasks::print (KTPrint& printer) const +{ + QFont stnd; + + stnd = printer.getFont(); + + printer.setFont(QFont( KGlobalSettings::generalFont().family(), 10, QFont::Bold )); + printer.print (i18n("Task name:"), 1, KTPrint::alignTextLeft); + printer.print (i18n("Program:"), 2, KTPrint::alignTextCenter); + printer.print (i18n("Description:"),3,KTPrint::alignTextRight); + + printer.setFont(stnd); + + //firstChild() does not return null if there are no children, therefore + //we need to check the validation of the pointer without terminating + //the application. This maybe a bug in QT 1.44 + + if (this->childCount() ==0) { + printer.print(i18n("No tasks..."),1,KTPrint::alignTextLeft, false); + printer.levelColumns(20); + return; + } + + KTListItem* ktli = (KTListItem*)this->firstChild(); + Q_CHECK_PTR(ktli); + + while (ktli) { + ktli->print(printer); + ktli = (KTListItem*)ktli->nextSibling(); + printer.levelColumns(); + } + printer.levelColumns(20); +} diff --git a/kcron/ktlisttasks.h b/kcron/ktlisttasks.h new file mode 100644 index 0000000..075edde --- /dev/null +++ b/kcron/ktlisttasks.h @@ -0,0 +1,62 @@ +/*************************************************************************** + * KT list view item cron tasks folder. * + * -------------------------------------------------------------------- * + * Copyright (C) 1999, Gary Meyer <gary@meyer.net> * + * -------------------------------------------------------------------- * + * 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. * + ***************************************************************************/ + +#ifndef KTLISTTASKS_H +#define KTLISTTASKS_H + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "ktlistitem.h" + +class QString; + +/** + * QListViewItem of a "tasks" folder. + */ +class KTListTasks : public KTListItem +{ +public: + +/** + * Construct tasks folder from branch. + */ + KTListTasks(KTListItem* parent, CTCron* _ctcron); + +/** + * Construct tasks folder from root. + */ + KTListTasks(QListView* parent, CTCron* _ctcron); + + /** + * Internationalized description. + */ + static QString getDescription(); + +/** + * Create. + */ + virtual void create(); + +/** + * Refresh. + */ + virtual void refresh(); + +/** + * Print all tasks. + */ + virtual void print(KTPrint &printer)const; + +}; + +#endif // KTLISTTASKS_H diff --git a/kcron/ktlistvar.cpp b/kcron/ktlistvar.cpp new file mode 100644 index 0000000..1157683 --- /dev/null +++ b/kcron/ktlistvar.cpp @@ -0,0 +1,80 @@ +/*************************************************************************** + * KT list view item variable implementation. * + * -------------------------------------------------------------------- * + * Copyright (C) 1999, Gary Meyer <gary@meyer.net> * + * -------------------------------------------------------------------- * + * 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. * + ***************************************************************************/ + +#include "ktlistvar.h" +#include "ktprint.h" + +#include <klocale.h> // i18n() + +#include "ctvariable.h" + +#include "kticon.h" +#include "ktvariable.h" + +KTListVar::KTListVar(KTListItem* parent, CTCron* _ctcron, + CTVariable* _ctvariable) : + KTListItem(parent, 0, _ctcron), + ctvar(_ctvariable) +{ + refresh(); + parent->setOpen(true); +} + +void KTListVar::refresh() +{ + setText (0,QString::fromLocal8Bit(ctvar->variable.c_str())); + + if (ctvar->enabled) + { + setText (1,QString::fromLocal8Bit(ctvar->value.c_str())); + setText (2,QString::fromLocal8Bit(ctvar->comment.c_str())); + } + else + { + setText(1, ""); + setText(2, i18n("Disabled")); + } + + if (ctvar->variable == "MAILTO") + setPixmap(0, KTIcon::mail(true)); + else if (ctvar->variable == "SHELL") + setPixmap(0, KTIcon::shell(true)); + else if (ctvar->variable == "HOME") + setPixmap(0, KTIcon::home(true)); + else if (ctvar->variable == "PATH") + setPixmap(0, KTIcon::path(true)); + else + setPixmap(0, KTIcon::variable(true)); +} + +void KTListVar::print(KTPrint& printer) const +{ + printer.print(QString::fromLocal8Bit(ctvar->variable.c_str()), 1, KTPrint::alignTextLeft); + if (ctvar->enabled) { + printer.print(QString::fromLocal8Bit(ctvar->value.c_str()),2, KTPrint::alignTextCenter); + printer.print(QString::fromLocal8Bit(ctvar->comment.c_str()),3,KTPrint::alignTextRight); + } + else + printer.print(i18n("Disabled."),3, KTPrint::alignTextRight); + +} + +void KTListVar::edit() +{ + KTVariable(ctvar,i18n("Modify Variable")).exec(); + refresh(); + parent()->sortChildItems(1, true); +} + +CTVariable* KTListVar::getCTVariable() const +{ + return ctvar; +} diff --git a/kcron/ktlistvar.h b/kcron/ktlistvar.h new file mode 100644 index 0000000..c5880a4 --- /dev/null +++ b/kcron/ktlistvar.h @@ -0,0 +1,63 @@ +/*************************************************************************** + * KT list view item variable header. * + * -------------------------------------------------------------------- * + * Copyright (C) 1999, Gary Meyer <gary@meyer.net> * + * -------------------------------------------------------------------- * + * 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. * + ***************************************************************************/ + +#ifndef KTLISTVAR_H +#define KTLISTVAR_H + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "ktlistitem.h" + +class CTVariable; + +/** + * QListViewItem with a CTVariable. + */ +class KTListVar : public KTListItem +{ +public: + +/** + * Initialize the list view item and environment variable. + */ + KTListVar(KTListItem* parent, CTCron* _ctcron, CTVariable* _ctvariable); + +/** + * Refresh from underlying variable. + */ + void refresh(); + +/** + * Print variable. + */ + void print(KTPrint &printer) const; + +/** + * Edit variable. + */ + virtual void edit(); + +/** + * Get the environment variable. + */ + CTVariable* getCTVariable() const; + +private: + +/** + * Environment variable. + */ + CTVariable* ctvar; +}; + +#endif // KTLISTVAR_H diff --git a/kcron/ktlistvars.cpp b/kcron/ktlistvars.cpp new file mode 100644 index 0000000..6bdde2d --- /dev/null +++ b/kcron/ktlistvars.cpp @@ -0,0 +1,99 @@ +/*************************************************************************** + * -------------------------------------------------------------------- * + * KT list view item cron variables folder implementation. * + * -------------------------------------------------------------------- * + * Copyright (C) 1999, Gary Meyer <gary@meyer.net> * + * -------------------------------------------------------------------- * + * 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. * + ***************************************************************************/ + +#include "ktlistvars.h" + +#include <qstring.h> + +#include <klocale.h> // i18n() +#include <kglobalsettings.h> + +#include "ctcron.h" +#include "ctvariable.h" + +#include "kticon.h" +#include "ktlistvar.h" +#include "ktvariable.h" +#include "ktprint.h" + +KTListVars::KTListVars(KTListItem* parent, CTCron* _ctcron) : + KTListItem(parent, 0, _ctcron) +{ + refresh(); +} + +KTListVars::KTListVars(QListView* parent, CTCron* _ctcron) : + KTListItem(parent, 0, _ctcron) +{ + refresh(); +} + +void KTListVars::create() +{ + CTVariable* tempvar = new CTVariable(); + KTVariable* ktvar = new KTVariable(tempvar,i18n("Edit Variable")); + ktvar->exec(); + delete ktvar; + if (tempvar->dirty()) + { + getCTCron()->variable.push_back(tempvar); + new KTListVar(this, getCTCron(), tempvar); // Qt will clean up + } + else + { + delete tempvar; + } +} + +void KTListVars::refresh() +{ + setText(0, getDescription()); + setPixmap(0, KTIcon::variables(true)); +} + +void KTListVars::print(KTPrint& printer) const +{ + QFont stnd; + + stnd = printer.getFont() ; + printer.setFont(QFont( KGlobalSettings::generalFont().family(), 10, QFont::Bold )); + + printer.print(i18n("Variable:"), 1, KTPrint::alignTextLeft); + printer.print(i18n("Value:"), 2, KTPrint::alignTextCenter); + printer.print(i18n("Description:"), 3, KTPrint::alignTextRight); + + printer.setFont(stnd); + + //firstChild() does not return null if there are no children, therefore + //we need to check the validation of the pointer without terminating + //the application. This maybe a bug in QT 1.44 + + if (this->childCount() ==0) { + printer.print(i18n("No variables..."),1,KTPrint::alignTextLeft, false); + printer.levelColumns(20); + return; + } + + KTListItem* ktli = (KTListItem*)this->firstChild(); + Q_CHECK_PTR(ktli); + while (ktli) { + ktli->print(printer); + ktli = (KTListItem*)ktli->nextSibling(); + printer.levelColumns(); + } + printer.levelColumns(20); +} + +QString KTListVars::getDescription() +{ + return i18n("Variables"); +} diff --git a/kcron/ktlistvars.h b/kcron/ktlistvars.h new file mode 100644 index 0000000..b338082 --- /dev/null +++ b/kcron/ktlistvars.h @@ -0,0 +1,63 @@ +/*************************************************************************** + * -------------------------------------------------------------------- * + * KT list view item cron variables folder. * + * -------------------------------------------------------------------- * + * Copyright (C) 1999, Gary Meyer <gary@meyer.net> * + * -------------------------------------------------------------------- * + * 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. * + ***************************************************************************/ + +#ifndef KTLISTVARS_H +#define KTLISTVARS_H + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "ktlistitem.h" + +class QString; + +/** + * QListViewItem of a "variables" folder. + */ +class KTListVars : public KTListItem +{ +public: + +/** + * Construct variables folder from branch. + */ + KTListVars(KTListItem* parent, CTCron* _ctcron); + +/** + * Construct variables folder from root. + */ + KTListVars(QListView* parent, CTCron* _ctcron); + +/** + * Internationalized description. + */ + static QString getDescription(); + +/** + * Refresh. + */ + void refresh(); + +/** + * print all variables. + */ + void print(KTPrint &printer) const; + +/** + * Edit. + */ + void create(); + +}; + +#endif // KTLISTVARS_H diff --git a/kcron/ktprint.cpp b/kcron/ktprint.cpp new file mode 100644 index 0000000..423b6a1 --- /dev/null +++ b/kcron/ktprint.cpp @@ -0,0 +1,188 @@ + +/*************************************************************************** + * -------------------------------------------------------------------- * + * KDE\QT printing implementation. * + * -------------------------------------------------------------------- * + * Copyright (C) 1999, Robert Berry <rjmber@ntlworld.com> * + * -------------------------------------------------------------------- * + * 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. * + ***************************************************************************/ + +#include <qpainter.h> +#include <qstring.h> +#include <qpaintdevicemetrics.h> + +#include <ktprintopt.h> +#include <klocale.h> +#include "ktprint.h" + +const int KTPrint::alignTextLeft (1000); +const int KTPrint::alignTextRight (2000); +const int KTPrint::alignTextCenter (3000); + +const int KTPrint::defaultLeftMargin (20); +const int KTPrint::defaultRightMargin (20); +const int KTPrint::defaultTopMargin (30); +const int KTPrint::defaultBottomMargin (30); + +/* + I had to add this enum to get the file to compile. Since I ported + this class to QT2.1.1 the compiler throws errors about these flags. + When I figure why I will fix this ugly solution. +*/ + +enum AlignmentFlags { AlignLeft = 0x0001, AlignRight = 0x0002, + AlignHCenter = 0x0004, AlignTop = 0x0008, + AlignBottom = 0x0010, AlignVCenter = 0x0020, + AlignCenter = AlignVCenter | AlignHCenter, + SingleLine = 0x0040, DontClip = 0x0080, + ExpandTabs = 0x0100, ShowPrefix = 0x0200, + WordBreak = 0x0400, DontPrint = 0x1000 }; + +KTPrint::~KTPrint() +{ + delete prnt; + if (columns.size()>0) + columns.erase(columns.begin(), columns.end()); + +} + +void KTPrint :: createColumns (unsigned num_columns) +{ +//Construct all of the columns to be equal in size +//I am going to add a function which works on percentages + + int start; + Column *col; + int col_width(width / num_columns); + + if (columns.size()>0) + columns.erase(columns.begin(), columns.end()); + + for (unsigned i = 0, start = leftMargin; i < num_columns; i++) { + col = new Column; + col->start = start; + col->finish = start + (col_width - 5); + col->height = topMargin; + columns.push_back(col); + start+=col_width; + } + +} + +bool KTPrint:: start () +{ + prnt->setDocName("Cron Tab"); + prnt->addDialogPage(new KTPrintOpt(root)); + + if (prnt->setup(0L, i18n("Print Cron Tab"))) { //Setup a printer + if (paint!=NULL) delete paint; + paint = new QPainter (); + paint->begin(prnt); + paint->setTabStops(20); // Setup a defualt tab stop size + + //Get the information about the page size + QPaintDeviceMetrics metrics (prnt); + width = metrics.width () - (leftMargin + rightMargin); + height = metrics.height () - (topMargin + bottomMargin); + return true; + } + else + return false; +} + +void KTPrint :: setFont (const QFont &font) +{ + paint->setFont(font); +} + +QFont KTPrint :: getFont () const +{ + return paint->font(); +} + +void KTPrint :: print (const QString &str, int col, int alignment, bool wordWrap) +{ +//Prints the string str into the column col using +//the remaining arguments as format flags + + int format; + + if (paint==NULL) + return; + + + //Setup the alignment + switch (alignment) { + case alignTextLeft : format = AlignLeft | AlignTop | DontClip | ExpandTabs; break; + case alignTextCenter : format = AlignHCenter | AlignTop | DontClip | ExpandTabs; break; + case alignTextRight : format = AlignRight | AlignTop | DontClip | ExpandTabs; break; + default : + //add error trap + break; + + } + + //Check if we are wrapping words + if (wordWrap) + format = format | WordBreak; + + //Whats left of the page + int remainder (height - columns[col-1]->height); + QRect rect=paint->boundingRect(columns[col-1]->start,columns[col-1]->height, columns[col-1]->width(), remainder,format, str); + + if (rect.height() <= remainder) + { + //Draw the text + paint->drawText(columns[col-1]->start,columns[col-1]->height, columns[col-1]->width(), remainder, format, str); + //Reset the columns height + columns[col-1]->height += rect.height(); + } + else + { + newPage(); + remainder = height - columns[col-1]->height; + rect=paint->boundingRect(columns[col-1]->start,columns[col-1]->height, columns[col-1]->width(), remainder,format, str); + paint->drawText(columns[col-1]->start,columns[col-1]->height, columns[col-1]->width(), remainder, format, str); + columns[col-1]->height += rect.height(); + } +} + +void KTPrint :: levelColumns(int space) +{ + int ht(0); + + //Find the heighest height + for (unsigned i(0); i < columns.size(); i++) { + if (ht < columns[i]->height) + ht = columns[i]->height; + } + + //Set all the columns to that height and then add the space argument + for (unsigned i(0); i < columns.size(); i++) + columns[i]->height = ht+space; +} + +void KTPrint :: finished () +{ + if (paint!=NULL) { + paint->end(); //Send to printer or file + delete paint; + } +} + +void KTPrint :: newPage () +{ + prnt->newPage(); + for (unsigned i(0); i < columns.size(); i++) + columns[i]->height = topMargin; +} + +int KTPrint :: numCopies () const +{ + return prnt->numCopies(); +} + diff --git a/kcron/ktprint.h b/kcron/ktprint.h new file mode 100644 index 0000000..da22ff3 --- /dev/null +++ b/kcron/ktprint.h @@ -0,0 +1,216 @@ + +/*************************************************************************** + * -------------------------------------------------------------------- * + * KDE\QT Printing class * + * -------------------------------------------------------------------- * + * Copyright (C) 1999, Robert Berry <rjmber@ntlworld.com> * + * -------------------------------------------------------------------- * + * 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. * + ***************************************************************************/ + +#ifndef KTPRINT_H +#define KTPRINT_H + +#include <vector> +#include <kprinter.h> + +class QPainter; +class KPrinter; +class QString; +class QFont; + +/** + *Provides a wrapper for simple printing of text. + */ +class KTPrint{ +public: + +/** + *Static formatting constants + */ + static const int alignTextLeft; + static const int alignTextRight; + static const int alignTextCenter; + +/** + *Static Default Margin Constants + */ + static const int defaultLeftMargin; + static const int defaultRightMargin; + static const int defaultTopMargin; + static const int defaultBottomMargin; + +/** + * Contructor + */ + KTPrint(bool _root) : + leftMargin(defaultLeftMargin), + rightMargin (defaultRightMargin), + topMargin(defaultTopMargin), + bottomMargin(defaultBottomMargin), + paint(0), + root(_root) + { + prnt = new KPrinter; + prnt->setOption("crontab","true"); + createColumns(1); + } + +/** + * Destructor + */ + ~KTPrint(); + +/** + * Start the printing process, gain page info + */ + bool start (); + +/** + * Send the information to the printer + */ + void finished (); + +/** + * Set the font to be used + */ + void setFont (const QFont &font); + +/** + * Get the current font + */ + QFont getFont ()const; + +/** + * Print text + */ + void print (const QString &str, int col =1, int alignment=KTPrint::defaultLeftMargin, bool wordWrap = true); + +/** + * Constructs the columns + */ + void createColumns(unsigned num_columns =1); + +/** + * Make sure that all columns start printing on the same line + */ + void levelColumns(int space = 5); + +/** + * Insert a new page + */ + void newPage(); + +/** + * + */ + int numCopies () const; + +/** + * Whether crontab should be printed + */ + bool crontab() const + { + return (prnt->option("crontab") == "true"); + } + +/** + * Whether all users should be printed (root only) + */ + bool allUsers() const + { + return (prnt->option("allusers") == "true"); + } +private: + + /** + *Disable the copy constructor and the assignment operator + */ + KTPrint (const KTPrint&) {} + KTPrint& operator=(const KTPrint&) {return *this;} + +/** + * Left boundary + */ + int leftMargin; + +/** + * Right boundary + */ + int rightMargin; + +/** + * Top boundary + */ + int topMargin; + +/** + * Bottom boundary + */ + int bottomMargin; + +/** + * Width of the page + */ + int width; + +/** + * Height of the page + */ + int height; + +/** + * Pointer to a painter object + */ + QPainter *paint; + +/** + * Whether we are root or not + */ + bool root; + +/** + * Pointer a printer object + */ + KPrinter *prnt; + +/** + *Nest a column class to make text layout nicer + */ + + class Column { + public: + + /** + *Starting X co-ord + */ + int start; + + /** + *Finishing X co-ord + */ + int finish; + + /** + *Current Y co-ord + */ + int height; + + + /** + *Return the width of the column + */ + int width () const {return finish-start;} + }; + +/** + * Keep a vector of the columns + */ + std::vector <Column*> columns; + +}; + +#endif diff --git a/kcron/ktprintopt.cpp b/kcron/ktprintopt.cpp new file mode 100644 index 0000000..68315c5 --- /dev/null +++ b/kcron/ktprintopt.cpp @@ -0,0 +1,68 @@ + +/*************************************************************************** + * -------------------------------------------------------------------- * + * Print Options Dialog * + * -------------------------------------------------------------------- * + * Copyright (C) 1999, Robert Berry <rjmber@ntlwolrd.com> * + * -------------------------------------------------------------------- * + * 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. * + ***************************************************************************/ + +#include <qcheckbox.h> +#include <qlayout.h> + +#include <kdialog.h> +#include <kaccel.h> +#include <klocale.h> +#include <kapplication.h> +#include "ktprintopt.h" + +KTPrintOpt::KTPrintOpt(bool root) : + KPrintDialogPage(0, "ktprintopt") +{ + m_title = i18n("Cron Options"); + + QVBoxLayout *main_ = new QVBoxLayout(this, KDialog::marginHint(), KDialog::spacingHint()); + + chkPrintCrontab = new QCheckBox(i18n("Print cron&tab"), this, "chkPrintCrontab"); + main_->addWidget(chkPrintCrontab); + + chkPrintAllUsers = new QCheckBox(i18n("Print &all users"), this, "chkPrintAllUsers"); + main_->addWidget(chkPrintAllUsers); + + if (!root) { + chkPrintAllUsers->setChecked(false); + chkPrintAllUsers->setEnabled(false); + } +} + +KTPrintOpt::~KTPrintOpt() +{ +} + +void +KTPrintOpt::setOptions(const QMap<QString,QString>& opts) +{ + QString value; + + value = opts["crontab"]; + chkPrintCrontab->setChecked(value == "true"); + + if (chkPrintAllUsers->isEnabled()) + { + value = opts["allusers"]; + chkPrintAllUsers->setChecked(value == "true"); + } +} + +void KTPrintOpt::getOptions(QMap<QString,QString>& opts, bool) +{ + opts["crontab"] = chkPrintCrontab->isChecked() ? "true" : "false"; + opts["allusers"] = chkPrintAllUsers->isChecked() ? "true" : "false"; +} + + +#include "ktprintopt.moc" diff --git a/kcron/ktprintopt.h b/kcron/ktprintopt.h new file mode 100644 index 0000000..0ab1810 --- /dev/null +++ b/kcron/ktprintopt.h @@ -0,0 +1,52 @@ + +/*************************************************************************** + * -------------------------------------------------------------------- * + * Print Options Dialog * + * -------------------------------------------------------------------- * + * Copyright (C) 1999, Robert Berry <rjmber@ntlwolrd.com> * + * -------------------------------------------------------------------- * + * 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. * + ***************************************************************************/ + +#ifndef KTPRINTOPT_H +#define KTPRINTOPT_H + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <kdeprint/kprintdialogpage.h> + +class QCheckBox; +class KAccel; + +/** + *Give the user the option to print the crontab file. + *If the user is root ask if they want to print all the users + */ + +class KTPrintOpt : public KPrintDialogPage +{ + Q_OBJECT +public: + +/** + * Constructs the dialog, if root is true the print all users is not disabled + */ + KTPrintOpt(bool root = false); + + ~KTPrintOpt(); + + void setOptions(const QMap<QString,QString>& options); + void getOptions(QMap<QString,QString>& options, bool incldef = false); + + +private: + QCheckBox* chkPrintCrontab; + QCheckBox* chkPrintAllUsers; +}; + +#endif diff --git a/kcron/kttask.cpp b/kcron/kttask.cpp new file mode 100644 index 0000000..8b78b49 --- /dev/null +++ b/kcron/kttask.cpp @@ -0,0 +1,900 @@ +/*************************************************************************** + * KT task editor window implementation * + * -------------------------------------------------------------------- * + * Copyright (C) 1999, Gary Meyer <gary@meyer.net> * + * -------------------------------------------------------------------- * + * 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. * + ***************************************************************************/ + +#include "kttask.h" + +#include <qlabel.h> +#include <qstring.h> +#include <qfileinfo.h> +#include <qlayout.h> +#include <qlineedit.h> +#include <qcheckbox.h> +#include <qbuttongroup.h> +#include <qpainter.h> +#include <qpalette.h> + +#include <kapplication.h> +#include <kaccel.h> +#include <klocale.h> +#include <kfiledialog.h> +#include <kmessagebox.h> +#include <kpushbutton.h> +#include <kstdguiitem.h> + +#include "cttask.h" + +#include "kticon.h" + +class KTPushButton : public QPushButton +{ +public: + KTPushButton(QWidget * parent, const char * name = 0 ) + : QPushButton(parent, name), isSelected(false), isDirty(false) + { + updatePalette(); + } + + void updatePalette() + { + palNormal = ((QWidget *)parent())->palette(); + palSelected = palNormal; + for(int cg = (int) QPalette::Disabled; cg < (int) QPalette::NColorGroups; cg++) + { + palSelected.setColor((QPalette::ColorGroup)cg, QColorGroup::Button, + palSelected.color((QPalette::ColorGroup)cg, QColorGroup::Highlight)); + palSelected.setColor((QPalette::ColorGroup)cg, QColorGroup::ButtonText, + palSelected.color((QPalette::ColorGroup)cg, QColorGroup::HighlightedText)); + } + isDirty = true; + } + + bool event( QEvent *e) + { + if (e->type() == QEvent::ParentPaletteChange) + { + updatePalette(); + update(); + } + return QPushButton::event(e); + } + + void drawButton ( QPainter *p ) + { + if (isDirty || (isOn() != isSelected)) // Prevent infinite recursion + { + isDirty = false; + isSelected = isOn(); + if (isSelected) + setPalette(palSelected); + else + setPalette(palNormal); + } + QPushButton::drawButton(p); + } + void drawButtonLabel ( QPainter *p ) + { + p->save(); + if (isOn()) + { + QFont f = p->font(); + f.setUnderline(true); + p->setFont(f); + } + QPushButton::drawButtonLabel(p); + p->restore(); + } + bool isSelected; + bool isDirty; + QPalette palSelected; + QPalette palNormal; +}; + +KTTask::KTTask(CTTask* _cttask, const QString & _caption) + :KDialog( 0, "kttask", true, WStyle_DialogBorder ) +{ + cttask = _cttask; + + bool everyDay(true); + + QVBoxLayout *ml = new QVBoxLayout( this, KDialogBase::spacingHint() ); + + QHBoxLayout *h1 = new QHBoxLayout( ml, KDialogBase::spacingHint() ); + + // user + labUser = new QLabel( i18n("&Run as:"), this, "labUser" ); + h1->addWidget( labUser ); + + leUser = new QLineEdit( this, "leUser"); + labUser->setBuddy(leUser); + h1->addWidget( leUser ); + + if (cttask->system()) + { + leUser->setText(QString::fromLocal8Bit(cttask->user.c_str())); + } + else + { + labUser->hide(); + leUser->hide(); + } + + // icon + labIcon = new QLabel(this, "labIcon"); + labIcon->setFixedSize(32, 32); + h1->addStretch( 1 ); + h1->addWidget( labIcon ); + + // comment + QHBoxLayout *h2 = new QHBoxLayout( ml, KDialogBase::spacingHint() ); + + labComment = new QLabel( i18n("&Comment:"), this, "labComment" ); + h2->addWidget( labComment ); + + leComment = new QLineEdit(this, "leComment"); + labComment->setBuddy(leComment); + h2->addWidget( leComment ); + + leComment->setText(QString::fromLocal8Bit(cttask->comment.c_str())); + + // command + QHBoxLayout *h3 = new QHBoxLayout( ml, KDialogBase::spacingHint() ); + + labCommand = new QLabel( i18n("&Program:"), this, "labCommand" ); + h3->addWidget( labCommand ); + + leCommand = new QLineEdit(this, "leCommand"); + labCommand->setBuddy(leCommand); + h3->addWidget( leCommand ); + + leCommand->setText(QString::fromLocal8Bit(cttask->command.c_str())); + + labComment->setFixedWidth( QMAX( labComment->width(), labCommand->width()) ); + labCommand->setFixedWidth( QMAX( labComment->width(), labCommand->width()) ); + + slotCommandChanged(); + + pbBrowse = new QPushButton(this, "pbBrowse"); + pbBrowse->setText(i18n("&Browse...")); + h3->addWidget( pbBrowse ); + + QHBoxLayout *h3a = new QHBoxLayout( ml, KDialogBase::spacingHint() ); + + // enabled + chkEnabled = new QCheckBox(i18n("&Enabled"), this, "chkEnabled"); + chkEnabled->setChecked(cttask->enabled); + h3a->addWidget( chkEnabled ); + + // enabled + chkSilent = new QCheckBox(i18n("&Silent"), this, "chkSilent"); + chkSilent->setChecked(cttask->silent); + h3a->addWidget( chkSilent ); + + QHBoxLayout *h4 = new QHBoxLayout( ml, KDialogBase::spacingHint() ); + + ml->addSpacing( 2 * KDialogBase::spacingHint() ); + + // months + bgMonth = new QButtonGroup( i18n("Months"), this, "bgMonth"); + h4->addWidget( bgMonth ); + + QVBoxLayout *vmonths = new QVBoxLayout( bgMonth, KDialogBase::spacingHint() ); + vmonths->addSpacing( 2 * KDialogBase::spacingHint() ); + + for (int mo = 1; mo <= 12; mo++) + { + cbMonth[mo] = new QCheckBox(bgMonth, "cbMonth"); + cbMonth[mo]->setText(QString::fromLocal8Bit(cttask->month.getName(mo).c_str())); + cbMonth[mo]->setChecked(cttask->month.get(mo)); + vmonths->addWidget( cbMonth[mo], AlignLeft ); + + if (!cttask->month.get(mo)) everyDay = false; + } + pbAllMonths = new QPushButton(bgMonth, "pbAllMonths"); + pbAllMonths->setText( i18n("Set All") ); + vmonths->addWidget( pbAllMonths, AlignLeft ); + + QVBoxLayout *v1 = new QVBoxLayout( h4, KDialogBase::spacingHint() ); + + // days of the month + bgDayOfMonth = new QButtonGroup( i18n("Days of Month"), this, "bgDayOfMonth"); + v1->addWidget( bgDayOfMonth ); + + QPushButton* day; + QString tmp; + + QVBoxLayout *vdays = new QVBoxLayout( bgDayOfMonth, KDialogBase::spacingHint() ); + vdays->addSpacing( 2 * KDialogBase::spacingHint() ); + QHBoxLayout *hdays = 0; + + for (int dm = 1; dm <= 31; dm++) + { + if( (dm % 7) == 1 ) + hdays = new QHBoxLayout( vdays, KDialogBase::spacingHint() ); + + day = new KTPushButton(bgDayOfMonth); + day->setFixedSize(25, 25); + day->setText(tmp.setNum(dm)); + day->setToggleButton(true); + day->setOn(cttask->dayOfMonth.get(dm)); + pbDayOfMonth[dm] = day; + if (!cttask->dayOfMonth.get(dm)) everyDay = false; + + hdays->addWidget( day, AlignLeft ); + } + hdays->addStretch( 1 ); + pbAllDaysOfMonth = new QPushButton(bgDayOfMonth, "pbAllDaysOfMonth"); + pbAllDaysOfMonth->setText( i18n("Set All") ); + hdays->addWidget( pbAllDaysOfMonth, AlignLeft ); + + // days of the week + bgDayOfWeek = new QButtonGroup( i18n("Days of Week"), this, "bgDayOfWeek"); + v1->addWidget( bgDayOfWeek ); + + QVBoxLayout *v3 = new QVBoxLayout( bgDayOfWeek, KDialogBase::spacingHint() ); + v3->addSpacing( 2 * KDialogBase::spacingHint() ); + + for (int dw = 1; dw <= 7; dw++) + { + cbDayOfWeek[dw] = new QCheckBox(bgDayOfWeek); + cbDayOfWeek[dw]->setText(QString::fromLocal8Bit(cttask->dayOfWeek.getName(dw).c_str())); + cbDayOfWeek[dw]->setChecked(cttask->dayOfWeek.get(dw)); + v3->addWidget( cbDayOfWeek[dw] ); + + if (!cttask->dayOfWeek.get(dw)) everyDay = false; + } + pbAllDaysOfWeek = new QPushButton(bgDayOfWeek, "pbAllDaysOfWeek"); + pbAllDaysOfWeek->setText( i18n("Set All") ); + v3->addWidget( pbAllDaysOfWeek, AlignLeft ); + + QVBoxLayout *v2 = new QVBoxLayout( h4, KDialogBase::spacingHint() ); + + // daily + bgEveryDay = new QButtonGroup( i18n("Daily"), this, "bgEveryDay"); + v2->addWidget( bgEveryDay ); + + QVBoxLayout *v9 = new QVBoxLayout( bgEveryDay, KDialogBase::spacingHint() ); + v9->addSpacing( 2 * KDialogBase::spacingHint() ); + + cbEveryDay = new QCheckBox( i18n("Run every day"), bgEveryDay, "cbEveryDay"); + cbEveryDay->setChecked(everyDay); + v9->addWidget( cbEveryDay ); + + // hours + bgHour = new QButtonGroup( i18n("Hours"), this, "bgHour"); + v2->addWidget( bgHour ); + QVBoxLayout *v4 = new QVBoxLayout( bgHour, KDialogBase::spacingHint() ); + v4->addSpacing( 2 * KDialogBase::spacingHint() ); + + labAM = new QLabel( i18n("AM"), bgHour, "labAM"); + labAM->setAlignment(AlignRight | AlignVCenter); + v4->addWidget( labAM ); + + + for (int ho = 0; ho <= 23; ho++) + { + pbHour[ho] = new KTPushButton(bgHour); + pbHour[ho]->setText(tmp.setNum(ho)); + pbHour[ho]->setToggleButton(true); + pbHour[ho]->setOn(cttask->hour.get(ho)); + pbHour[ho]->setFixedSize(25, 25); + } + + QHBoxLayout *hhours = new QHBoxLayout( v4, KDialogBase::spacingHint() ); + for (int ho1 = 0; ho1 <= 11; ho1++) + { + if( ho1 == 6 ) + hhours = new QHBoxLayout( v4, KDialogBase::spacingHint() ); + + hhours->addWidget( pbHour[ho1] ); + } + + labPM = new QLabel( i18n("PM"), bgHour, "labPM"); + labPM->setAlignment(AlignRight | AlignVCenter); + v4->addWidget( labPM ); + + hhours = new QHBoxLayout( v4, KDialogBase::spacingHint() ); + for (int ho1 = 12; ho1 <= 23; ho1++) + { + if( ho1 == 18 ) + hhours = new QHBoxLayout( v4, KDialogBase::spacingHint() ); + + hhours->addWidget( pbHour[ho1] ); + } + + hhours = new QHBoxLayout( v4, KDialogBase::spacingHint() ); + pbAllHours = new QPushButton(bgHour, "pbAllHours"); + pbAllHours->setText( i18n("Set All") ); + hhours->addWidget( pbAllHours, AlignLeft ); + + // minutes + bgMinute = new QButtonGroup( i18n("Minutes"), this, "bgMinute"); + v2->addWidget( bgMinute ); + QVBoxLayout *vmin = new QVBoxLayout( bgMinute, KDialogBase::spacingHint() ); + vmin->addSpacing( 2 * KDialogBase::spacingHint() ); + + for (int mi = 0; mi <= 55; mi+=5) + { + pbMinute[mi] = new KTPushButton(bgMinute); + pbMinute[mi]->setText(tmp.setNum(mi)); + pbMinute[mi]->setToggleButton(true); + pbMinute[mi]->setOn(cttask->minute.get(mi)); + pbMinute[mi]->setFixedSize(25, 25); + } + + QHBoxLayout *hmin = new QHBoxLayout( vmin, KDialogBase::spacingHint() ); + for (int mi1 = 0; mi1 <= 55; mi1+=5) + { + if( mi1 == 30 ) + hmin = new QHBoxLayout( vmin, KDialogBase::spacingHint() ); + + hmin->addWidget( pbMinute[mi1] ); + } + + hmin = new QHBoxLayout( vmin, KDialogBase::spacingHint() ); + pbAllMinutes = new QPushButton(bgMinute, "pbAllMinutes"); + pbAllMinutes->setText( i18n("Set All") ); + hmin->addWidget( pbAllMinutes, AlignLeft ); + + QHBoxLayout *h5 = new QHBoxLayout( ml, KDialogBase::spacingHint() ); + h5->addStretch( 1 ); + + // OK + pbOk = new KPushButton(KStdGuiItem::ok(), this, "pbOk"); + pbOk->setDefault(true); + h5->addWidget( pbOk ); + + // Cancel + pbCancel = new KPushButton(KStdGuiItem::cancel(), this, "pbCancel"); + h5->addWidget( pbCancel ); + + // window + setIcon(KTIcon::application(true)); + setCaption(_caption/*i18n("Edit Task")*/); + + // set focus to first widget + if (cttask->system()) + { + leUser->setFocus(); + } + else + { + leComment->setFocus(); + } + + // connect them up + connect(pbBrowse, SIGNAL(clicked()), SLOT(slotBrowse())); + connect(leCommand, SIGNAL(textChanged(const QString&)), + SLOT(slotCommandChanged())); + connect(cbEveryDay, SIGNAL(clicked()), SLOT(slotDailyChanged())); + connect(pbOk, SIGNAL(clicked()), SLOT(slotOK())); + connect(pbCancel, SIGNAL(clicked()), SLOT(slotCancel())); + connect(pbAllMonths, SIGNAL(clicked()), SLOT(slotAllMonths())); + for (int mo = 1; mo <= 12; mo++) { + connect(cbMonth[mo], SIGNAL(clicked()), SLOT(slotMonthChanged())); + } + connect(pbAllDaysOfMonth, SIGNAL(clicked()), SLOT(slotAllDaysOfMonth())); + for (int dm = 1; dm <= 31; dm++) + { + connect(pbDayOfMonth[dm], SIGNAL(clicked()), SLOT(slotDayOfMonthChanged())); + } + connect(pbAllDaysOfWeek, SIGNAL(clicked()), SLOT(slotAllDaysOfWeek())); + for (int dw = 1; dw <= 7; dw++) + { + connect(cbDayOfWeek[dw], SIGNAL(clicked()), SLOT(slotDayOfWeekChanged())); + } + connect(pbAllHours, SIGNAL(clicked()), SLOT(slotAllHours())); + for (int ho = 0; ho <= 23; ho++) + { + connect(pbHour[ho], SIGNAL(clicked()), SLOT(slotHourChanged())); + } + connect(pbAllMinutes, SIGNAL(clicked()), SLOT(slotAllMinutes())); + for (int mi = 0; mi <= 55; mi+=5) + { + connect(pbMinute[mi], SIGNAL(clicked()), SLOT(slotMinuteChanged())); + } + + // key acceleration + key_accel = new KAccel(this); + key_accel->insert(KStdAccel::Open, this, SLOT(slotOK())); + key_accel->insert(KStdAccel::Close, this, SLOT(slotCancel())); + key_accel->insert(KStdAccel::Quit, this, SLOT(slotCancel())); + key_accel->readSettings(); + + setFixedSize( minimumSize() ); + slotDailyChanged(); + slotMonthChanged(); + slotDayOfMonthChanged(); + slotDayOfWeekChanged(); + slotHourChanged(); + slotMinuteChanged(); +} + +KTTask::~KTTask() +{ +} + +void KTTask::slotCommandChanged() +{ + /* + QString qs(leCommand->text()); + + int beginPos(qs.findRev("/", qs.length()) + 1); + if (beginPos < 0) beginPos = 0; + + int endPos(qs.findRev(" ", qs.length())); + if (endPos < 0) endPos = qs.length(); + + QString iconName(qs.mid(beginPos, endPos-beginPos) + ".xpm"); + + QPixmap qp(KTIcon::getIcon(iconName)); + if (qp.isNull()) + labIcon->setPixmap(KTIcon::task(false)); + else + labIcon->setPixmap(qp); + */ + + labIcon->setPixmap(KTIcon::task(false)); + return; +} + +void KTTask::slotDailyChanged() +{ + if (cbEveryDay->isChecked()) + { + for (int mo = 1; mo <= 12; mo++) + { + cbMonth[mo]->setChecked(true); + cbMonth[mo]->setEnabled(false); + } + for (int dm = 1; dm <= 31; dm++) + { + pbDayOfMonth[dm]->setOn(true); + pbDayOfMonth[dm]->setEnabled(false); + } + for (int dw = 1; dw <= 7; dw++) + { + cbDayOfWeek[dw]->setChecked(true); + cbDayOfWeek[dw]->setEnabled(false); + } + pbAllMonths->setEnabled(false); + pbAllDaysOfMonth->setEnabled(false); + pbAllDaysOfWeek->setEnabled(false); + } + else + { + for (int mo = 1; mo <= 12; mo++) + { + cbMonth[mo]->setEnabled(true); + } + for (int dm = 1; dm <= 31; dm++) + { + pbDayOfMonth[dm]->setEnabled(true); + } + for (int dw = 1; dw <= 7; dw++) + { + cbDayOfWeek[dw]->setEnabled(true); + } + pbAllMonths->setEnabled(true); + pbAllDaysOfMonth->setEnabled(true); + pbAllDaysOfWeek->setEnabled(true); + } + slotMonthChanged(); + slotDayOfMonthChanged(); + slotDayOfWeekChanged(); +} + +void KTTask::slotOK() +{ + // Make it friendly for just selecting days of the month or + // days of the week. + + int monthDaysSelected(0); + for (int dm = 1; dm <= 31; dm++) + { + if (pbDayOfMonth[dm]->isOn()) monthDaysSelected++; + } + + int weekDaysSelected(0); + for (int dw = 1; dw <= 7; dw++) + { + if (cbDayOfWeek[dw]->isChecked()) weekDaysSelected++; + } + + if ((monthDaysSelected == 0) && (weekDaysSelected > 0)) + { + for (int dm = 1; dm <= 31; dm++) + { + pbDayOfMonth[dm]->setOn(1); + } + } + + if ((weekDaysSelected == 0) && (monthDaysSelected > 0)) + { + for (int dw = 1; dw <= 7; dw++) + { + cbDayOfWeek[dw]->setChecked(1); + } + } + + // Now validate + QString message(i18n("Please enter the following to schedule the task:\n")); + QString sep("\n- "); + bool showMessage(false); + + if (leCommand->text().isEmpty()) + { + message += sep + i18n("the program to run"); + leCommand->setFocus(); + showMessage = true; + } + + bool valid(false); + for (int mo = 1; mo <= 12; mo++) + { + if (cbMonth[mo]->isChecked()) valid = true; + } + if (!valid) + { + message += sep + i18n("the months"); + if (!showMessage) + { + cbMonth[1]->setFocus(); + } + showMessage = true; + } + + valid = false; + for (int dm = 1; dm <= 31; dm++) + { + if (pbDayOfMonth[dm]->isOn()) valid = true; + } + for (int dw = 1; dw <= 7; dw++) + { + if (cbDayOfWeek[dw]->isChecked()) valid = true; + } + + if (!valid) + { + message += sep + + i18n("either the days of the month or the days of the week"); + if (!showMessage) + { + pbDayOfMonth[1]->setFocus(); + } + showMessage = true; + } + + valid = false; + for (int ho = 0; ho <= 23; ho++) + { + if (pbHour[ho]->isOn()) valid = true; + } + + if (!valid) + { + message += sep + i18n("the hours"); + if (!showMessage) + { + pbHour[0]->setFocus(); + } + showMessage = true; + } + + valid = false; + for (int mi1 = 0; mi1 <= 55; mi1+=5) + { + if (pbMinute[mi1]->isOn()) valid = true; + } + + if (!valid) + { + message += sep + i18n("the minutes"); + if (!showMessage) + { + pbMinute[0]->setFocus(); + } + showMessage = true; + } + + if (showMessage) + { + KMessageBox::information(this, message); + return; + } + + // make sure the file name is a good one if we have an + // absolute path + + QString qs(leCommand->text()); + if (qs.find("/") == 0) + { + int spacePos(qs.find(" ")); + if (spacePos < 0) spacePos = qs.length(); + QString programName(qs.left(spacePos)); + QFileInfo file(programName); + + if (!file.isReadable()) + { + KMessageBox::information(this, + i18n("Cannot locate program. Please re-enter.")); + leCommand->setFocus(); + return; + } + + if (!file.isExecutable()) + { + KMessageBox::information(this, + i18n("Program is not an executable file. Please re-enter.")); + leCommand->setFocus(); + return; + } + } + + // save work in process + if (!cttask->user.empty()) + { + cttask->user = QFile::encodeName(leUser->text()); + } + else + { + cttask->user = ""; + } + + cttask->comment = (const char *)leComment->text().local8Bit(); + cttask->command = (const char *)leCommand->text().local8Bit(); + cttask->enabled = chkEnabled->isChecked(); + cttask->silent = chkSilent->isChecked(); + + for (int mo = 1; mo <= 12; mo++) + { + cttask->month.set(mo, cbMonth[mo]->isChecked()); + } + + for (int dm = 1; dm <= 31; dm++) + { + cttask->dayOfMonth.set(dm, pbDayOfMonth[dm]->isOn()); + } + for (int dw = 1; dw <= 7; dw++) + { + cttask->dayOfWeek.set(dw, cbDayOfWeek[dw]->isChecked()); + } + for (int ho = 0; ho <= 23; ho++) + { + cttask->hour.set(ho, pbHour[ho]->isOn()); + } + for (int mi = 0; mi <= 59; mi++) + { + cttask->minute.set(mi, false); + } + for (int mi1 = 0; mi1 <= 55; mi1+=5) + { + cttask->minute.set(mi1, pbMinute[mi1]->isOn()); + } + + close(); +} + +void KTTask::slotCancel() +{ + close(); +} + +void KTTask::slotBrowse() +{ + KURL url = KFileDialog::getOpenURL(); + + if(!url.isEmpty()) + { + if(url.isLocalFile()) + { + leCommand->setText(url.path()); + } + else + { + KMessageBox::sorry(this, + i18n("Only local or mounted files can be executed by crontab.")); + } + } + + leCommand->setFocus(); +} + +void KTTask::slotAllMonths() +{ + if (pbAllMonths->text() == i18n("Set All")) { + for (int mo = 1; mo <= 12; mo++) + { + cbMonth[mo]->setChecked(true); + } + } + else { + for (int mo = 1; mo <= 12; mo++) + { + cbMonth[mo]->setChecked(false); + } + } + slotMonthChanged(); +} + +void KTTask::slotMonthChanged() +{ + bool allChecked = true; + bool allCleared = true; + for (int mo = 1; mo <= 12; mo++) + { + if (cbMonth[mo]->isChecked()) { + allCleared = false; + } + else { + allChecked = false; + } + } + if (allCleared) { + pbAllMonths->setText( i18n("Set All") ); + } + else { + pbAllMonths->setText( i18n("Clear All") ); + } +} + +void KTTask::slotAllDaysOfMonth() +{ + if (pbAllDaysOfMonth->text() == i18n("Set All")) { + for (int dm = 1; dm <= 31; dm++) + { + pbDayOfMonth[dm]->setOn(true); + } + } + else { + for (int dm = 1; dm <= 31; dm++) + { + pbDayOfMonth[dm]->setOn(false); + } + } + slotDayOfMonthChanged(); +} + +void KTTask::slotDayOfMonthChanged() +{ + bool allChecked = true; + bool allCleared = true; + for (int dm = 1; dm <= 31; dm++) + { + if (pbDayOfMonth[dm]->isOn()) { + allCleared = false; + } + else { + allChecked = false; + } + } + if (allCleared) { + pbAllDaysOfMonth->setText( i18n("Set All") ); + } + else { + pbAllDaysOfMonth->setText( i18n("Clear All") ); + } + } + +void KTTask::slotAllDaysOfWeek() +{ + if (pbAllDaysOfWeek->text() == i18n("Set All")) { + for (int dw = 1; dw <= 7; dw++) + { + cbDayOfWeek[dw]->setChecked(true); + } + } + else { + for (int dw = 1; dw <= 7; dw++) + { + cbDayOfWeek[dw]->setChecked(false); + } + } + slotDayOfWeekChanged(); +} + +void KTTask::slotDayOfWeekChanged() +{ + bool allChecked = true; + bool allCleared = true; + for (int dw = 1; dw <= 7; dw++) + { + if (cbDayOfWeek[dw]->isChecked()) { + allCleared = false; + } + else { + allChecked = false; + } + } + if (allCleared) { + pbAllDaysOfWeek->setText( i18n("Set All") ); + } + else { + pbAllDaysOfWeek->setText( i18n("Clear All") ); + } + } + +void KTTask::slotAllHours() +{ + if (pbAllHours->text() == i18n("Set All")) { + for (int ho = 0; ho <= 23; ho++) + { + pbHour[ho]->setOn(true); + } + } + else { + for (int ho = 0; ho <= 23; ho++) + { + pbHour[ho]->setOn(false); + } + } + slotHourChanged(); +} + +void KTTask::slotHourChanged() +{ + bool allChecked = true; + bool allCleared = true; + for (int ho = 0; ho <= 23; ho++) + { + if (pbHour[ho]->isOn()) { + allCleared = false; + } + else { + allChecked = false; + } + } + if (allCleared) { + pbAllHours->setText( i18n("Set All") ); + } + else { + pbAllHours->setText( i18n("Clear All") ); + } + } + +void KTTask::slotAllMinutes() +{ + if (pbAllMinutes->text() == i18n("Set All")) { + for (int mi = 0; mi <= 55; mi+=5) + { + pbMinute[mi]->setOn(true); + } + } + else { + for (int mi = 0; mi <= 55; mi+=5) + { + pbMinute[mi]->setOn(false); + } + } + slotMinuteChanged(); +} + +void KTTask::slotMinuteChanged() +{ + bool allChecked = true; + bool allCleared = true; + for (int mi = 0; mi <= 55; mi+=5) + { + if (pbMinute[mi]->isOn()) { + allCleared = false; + } + else { + allChecked = false; + } + } + if (allCleared) { + pbAllMinutes->setText( i18n("Set All") ); + } + else { + pbAllMinutes->setText( i18n("Clear All") ); + } + } + +#include "kttask.moc" diff --git a/kcron/kttask.h b/kcron/kttask.h new file mode 100644 index 0000000..7920593 --- /dev/null +++ b/kcron/kttask.h @@ -0,0 +1,184 @@ +/*************************************************************************** + * KT task editor window header * + * -------------------------------------------------------------------- * + * Copyright (C) 1999, Gary Meyer <gary@meyer.net> * + * -------------------------------------------------------------------- * + * 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. * + ***************************************************************************/ + +#ifndef KTTASK_H +#define KTTASK_H + +#include <config.h> + +#include <kdialog.h> + +class QLabel; +class QLineEdit; +class QCheckBox; +class QButtonGroup; +class QPushButton; +class KAccel; + +class CTTask; + +/** + * Task editor window. + */ +class KTTask : public KDialog +{ + Q_OBJECT + +public: + +/** + * Initialize from CTTask. + */ + KTTask(CTTask* _cttask = 0, const QString &_caption=""); + +/** + * Destroy. + */ + ~KTTask(); + +private slots: + +/** + * Browse for command file. + */ + void slotBrowse(); + +/** + * Command has been changed. Refresh icon. + */ + void slotCommandChanged(); + +/** + * Daily checkbox has been changed. + */ + void slotDailyChanged(); + +/** + * Apply changes and close. + */ + void slotOK(); + +/** + * Cancel and close. + */ + void slotCancel(); + +/** + * Set or clear all month checkboxes + */ + void slotAllMonths(); + +/** + * A month checkbox has changed + */ + void slotMonthChanged(); + +/** + * Set or clear all day of month checkboxes + */ + void slotAllDaysOfMonth(); + +/** + * A day of month checkbox has changed + */ + void slotDayOfMonthChanged(); + +/** + * Set or clear all day of week checkboxes + */ + void slotAllDaysOfWeek(); + +/** + * A day of week checkbox has changed + */ + void slotDayOfWeekChanged(); + +/** + * Set or clear all hour checkboxes + */ + void slotAllHours(); + +/** + * An hour checkbox has changed + */ + void slotHourChanged(); + +/** + * Set or clear all minute checkboxes + */ + void slotAllMinutes(); + +/** + * A minute checkbox has changed + */ + void slotMinuteChanged(); + +private: + +/** + * Task. + */ + CTTask* cttask; + +/** + * Key accelerator. + */ + + KAccel* key_accel; + + // Widgets. + + QLabel* labUser; + QLineEdit* leUser; + + QLabel* labIcon; + + QLabel* labComment; + QLineEdit* leComment; + + QLabel* labCommand; + QLineEdit* leCommand; + QPushButton* pbBrowse; + + QCheckBox* chkEnabled; + QCheckBox* chkSilent; + + QButtonGroup* bgMonth; + QCheckBox* cbMonth[13]; + QPushButton* pbAllMonths; + + QButtonGroup* bgDayOfMonth; + QPushButton* pbDayOfMonth[32]; + QPushButton* pbAllDaysOfMonth; + + QButtonGroup* bgDayOfWeek; + QCheckBox* cbDayOfWeek[8]; + QPushButton* pbAllDaysOfWeek; + + QButtonGroup* bgEveryDay; + QCheckBox* cbEveryDay; + + QButtonGroup* bgHour; + QLabel* labAM; + QLabel* labPM; + QPushButton* pbHour[25]; + QPushButton* pbAllHours; + + QButtonGroup* bgMinute; + QPushButton* pbMinute[61]; + QPushButton* pbAllMinutes; + + QPushButton* pbOk; + QPushButton* pbCancel; + +}; + +#endif // KTTASK_H diff --git a/kcron/ktvariable.cpp b/kcron/ktvariable.cpp new file mode 100644 index 0000000..014bdf6 --- /dev/null +++ b/kcron/ktvariable.cpp @@ -0,0 +1,152 @@ +/*************************************************************************** + * KT environment variable editor window implementation * + * -------------------------------------------------------------------- * + * Copyright (C) 1999, Gary Meyer <gary@meyer.net> * + * -------------------------------------------------------------------- * + * 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. * + ***************************************************************************/ + +#include "ktvariable.h" + +#include <qlayout.h> + +#include <kapplication.h> // kapp +#include <klocale.h> // i18n() +#include <kmessagebox.h> +#include <ktextedit.h> + +#include "ctvariable.h" + +#include "kticon.h" + +KTVariable::KTVariable(CTVariable* _ctvar,const QString &_caption) : + KDialogBase(0, "ktvariable", true, _caption, Ok|Cancel, Ok, true), + ctvar( _ctvar) +{ + QFrame *page = makeMainWidget(); + QGridLayout *layout = new QGridLayout( page, 5, 3, 0, spacingHint() ); + layout->setRowStretch(3, 1); + layout->setColStretch(1, 1); + + setIcon(KTIcon::application(true)); + + // variable + labVariable = new QLabel(i18n("&Variable:"), page, "labVariable"); + layout->addWidget(labVariable, 1, 0, Qt::AlignLeft | Qt::AlignTop); + + cmbVariable = new QComboBox(true, page, "cmbVariable"); + layout->addWidget(cmbVariable, 1, 1); + + cmbVariable->insertItem("HOME"); + cmbVariable->insertItem("MAILTO"); + cmbVariable->insertItem("PATH"); + cmbVariable->insertItem("SHELL"); + + labVariable->setBuddy(cmbVariable); + + // icon + labIcon = new QLabel(page, "labIcon"); + layout->addMultiCellWidget(labIcon, 0, 1, 2, 2); + + // value + labValue = new QLabel(i18n("Va&lue:"), page, "labValue"); + layout->addWidget(labValue, 2, 0, Qt::AlignLeft | Qt::AlignTop); + + leValue = new QLineEdit(page, "leValue"); + layout->addMultiCellWidget(leValue, 2, 2, 1, 2); + leValue->setMaxLength(255); + labValue->setBuddy(leValue); + + // comment + labComment = new QLabel(i18n("Co&mment:"), page, "labComment"); + layout->addWidget(labComment, 3, 0, Qt::AlignLeft | Qt::AlignTop); + + teComment = new KTextEdit(page, "teComment"); + teComment->setTextFormat(Qt::PlainText); + layout->addMultiCellWidget(teComment, 3, 3, 1, 2); + + labComment->setBuddy(teComment); + + // enabled + chkEnabled = new QCheckBox(i18n("&Enabled"), page, "chkEnabled"); + layout->addWidget(chkEnabled, 4, 0); + + // set starting field values + cmbVariable->setEditText(QString::fromLocal8Bit(ctvar->variable.c_str())); + slotVariableChanged(); + + leValue->setText(QString::fromLocal8Bit(ctvar->value.c_str())); + + teComment->setText(QString::fromLocal8Bit(ctvar->comment.c_str())); + + chkEnabled->setChecked(ctvar->enabled); + + cmbVariable->setFocus(); + + // connect them up + connect(cmbVariable,SIGNAL(highlighted(const QString&)), + SLOT(slotVariableChanged())); + connect(cmbVariable,SIGNAL(activated(const QString&)), + SLOT(slotVariableChanged())); +} + +KTVariable::~KTVariable() +{ +} + +void KTVariable::slotVariableChanged() +{ + QString variable = cmbVariable->currentText(); + if (variable == "HOME") + { + labIcon->setPixmap(KTIcon::home(false)); + teComment->setText(i18n("Override default home folder.")); + } + else if (variable == "MAILTO") + { + labIcon->setPixmap(KTIcon::mail(false)); + teComment->setText(i18n("Email output to specified account.")); + } + else if (variable == "SHELL") + { + labIcon->setPixmap(KTIcon::shell(false)); + teComment->setText(i18n("Override default shell.")); + } + else if (variable == "PATH") + { + labIcon->setPixmap(KTIcon::path(false)); + teComment->setText(i18n("Folders to search for program files.")); + } + else + { + labIcon->setPixmap(KTIcon::variable(false)); + } +} + +void KTVariable::slotOk() +{ + if (cmbVariable->currentText().isEmpty()) + { + KMessageBox::information(this, i18n("Please enter the variable name.")); + cmbVariable->setFocus(); + return; + } + + if (leValue->text().isEmpty()) + { + KMessageBox::information(this, i18n("Please enter the variable value.")); + cmbVariable->setFocus(); + return; + } + + ctvar->variable = cmbVariable->currentText().local8Bit(); + ctvar->value = leValue->text().local8Bit(); + ctvar->comment = teComment->text().replace('\n',' ').replace('\r',' ').local8Bit(); + ctvar->enabled = chkEnabled->isChecked(); + close(); +} + +#include "ktvariable.moc" diff --git a/kcron/ktvariable.h b/kcron/ktvariable.h new file mode 100644 index 0000000..eb5eb57 --- /dev/null +++ b/kcron/ktvariable.h @@ -0,0 +1,84 @@ +/*************************************************************************** + * KT environment variable editor window header * + * -------------------------------------------------------------------- * + * Copyright (C) 1999, Gary Meyer <gary@meyer.net> * + * -------------------------------------------------------------------- * + * 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. * + ***************************************************************************/ + +#ifndef KTVARIABLE_H +#define KTVARIABLE_H + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <qlabel.h> +#include <qlineedit.h> +#include <qcombobox.h> +#include <qcheckbox.h> + +#include <kdialogbase.h> + +class KTextEdit; + +class CTVariable; + +/** + * Environment variable editor window. + */ +class KTVariable : public KDialogBase +{ + Q_OBJECT + +public: + +/** + * Initialize from CTVariable. + */ + KTVariable(CTVariable* _ctvar = 0, const QString &_caption=""); + +/** + * Destroy. + */ + ~KTVariable(); + +private slots: + +/** + * Variable name has been changed. Refresh icon. + */ + void slotVariableChanged(); + + /** + * Apply changes and close. + */ + void slotOk(); + +private: + +/** + * Environment variable. + */ + CTVariable* ctvar; + + // Widgets. + + QLabel* labIcon; + + QLabel* labVariable; + QComboBox* cmbVariable; + + QLabel* labValue; + QLineEdit* leValue; + + QLabel* labComment; + KTextEdit* teComment; + + QCheckBox* chkEnabled; +}; + +#endif // KTVARIABLE_H diff --git a/kcron/ktview.cpp b/kcron/ktview.cpp new file mode 100644 index 0000000..87c90c0 --- /dev/null +++ b/kcron/ktview.cpp @@ -0,0 +1,576 @@ +/************************************************************************** + * KT main GUI view implementation * + * -------------------------------------------------------------------- * + * Copyright (C) 1999, Gary Meyer <gary@meyer.net> * + * -------------------------------------------------------------------- * + * 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. * + ***************************************************************************/ + +#include "ktview.h" + +#include <stdlib.h> +#include <unistd.h> + +#include <config.h> + +#ifdef HAVE_SSTREAM +#include <sstream> +#else +#include <strstream.h> +#endif + +#include <string> + +#include <qstring.h> +#include <qheader.h> +#include <qpopupmenu.h> +#include <qfileinfo.h> +#include <qfile.h> +#include <qdatetime.h> + +#include <kapplication.h> +#include <kglobalsettings.h> +#include <klocale.h> + +#include "cthost.h" +#include "ctcron.h" +#include "ctvariable.h" +#include "cttask.h" + +#include "kticon.h" +#include "ktlistcron.h" +#include "ktlistvars.h" +#include "ktlistvar.h" +#include "ktlisttasks.h" +#include "ktlisttask.h" +#include "ktapp.h" +#include "ktvariable.h" +#include "kttask.h" +#include "ktprint.h" + +KTView::KTView(QWidget *parent, const char* name) : + QWidget(parent, name), + listView(0), + currentCTCron(0), + currentIsTask(true), + currentCTTask(0), + currentCTVariable(0), + clipboardIsTask(true), + clipboardCTTask(0), + clipboardCTVariable(0) +{ + ktapp = (KTApp*)parentWidget(); + setBackgroundMode(PaletteBase); + refresh(); + listView->setSelected(listView->firstChild(), true); + + connect(this, SIGNAL(enableModificationButtons(bool)), parent, + SLOT(slotEnableModificationButtons(bool))); + + connect(this, SIGNAL(enablePaste(bool)), parent, + SLOT(slotEnablePaste(bool))); + + connect(this, SIGNAL(enableRunNow(bool)), parent, + SLOT(slotEnableRunNow(bool))); + + connect(this, SIGNAL(enableEnabled(bool)), parent, + SLOT(slotEnableEnabled(bool))); +} + +void KTView::disableIcons() +{ + emit(enableModificationButtons(false)); + emit(enablePaste(clipboardCTVariable)); + emit(enableRunNow(false)); +} + +void KTView::refresh() +{ + QListView* tmpListView(listView); + + listView = new QListView(this); + + listView->setFrameStyle(QListView::Panel | QListView::Sunken); + listView->setRootIsDecorated(true); + listView->setAllColumnsShowFocus(true); + listView->setShowSortIndicator(true); + + const CTHost& cth(ktapp->getCTHost()); + + if (cth.root()) + listView->addColumn(i18n("Users/Tasks/Variables")); + else + listView->addColumn(i18n("Tasks/Variables")); + + listView->addColumn(i18n("Value")); + listView->addColumn(i18n("Description")); + + for (int item = 0; item <=2; item++) + listView->setColumnWidthMode(item, QListView::Maximum); + + // for each user + for (CTCronIterator i = const_cast<CTHost&>(cth).cron.begin(); + i != cth.cron.end(); i++) + { + CTCron* ctcron((CTCron*)*i); + + KTListVars* variables(0); + KTListTasks* tasks(0); + + if (cth.root()) + { + KTListCron* user = new KTListCron(listView, ctcron); + if (currentCTCron == ctcron) + { + listView->setSelected(user, true); + } + + variables = new KTListVars(user, ctcron); + tasks = new KTListTasks(user, ctcron); + } + else + { + variables = new KTListVars(listView, ctcron); + tasks = new KTListTasks(listView, ctcron); + } + + if (currentIsTask) + { + listView->setSelected(tasks, true); + slotSetCurrent(tasks); + } + else + { + listView->setSelected(variables, true); + slotSetCurrent(variables); + } + + for (CTVariableIterator j = (CTVariableIterator)ctcron->variable.begin(); + j != ctcron->variable.end(); j++) + { + new KTListVar(variables, ctcron, (CTVariable*)*j); + } + + for (CTTaskIterator k = (CTTaskIterator)ctcron->task.begin(); + k != ctcron->task.end(); k++) + { + new KTListTask(tasks, ctcron, (CTTask*)*k); + } + } + + resizeEvent(); + + connect(listView, SIGNAL(contextMenuRequested(QListViewItem*, const QPoint&, int)), + SLOT(slotMenu(QListViewItem*, const QPoint&, int))); + + connect(listView, SIGNAL(selectionChanged(QListViewItem*)), + SLOT(slotSetCurrent(QListViewItem*))); + + connect(listView, SIGNAL(doubleClicked(QListViewItem*)), + SLOT(slotEdit(QListViewItem*))); + + connect(listView, SIGNAL(returnPressed(QListViewItem*)), + SLOT(slotEdit(QListViewItem*))); + + // switch to the new view + if (tmpListView) + { + tmpListView->hide(); + listView->show(); + listView->setFocus(); + delete tmpListView; + } +} + +void KTView::print () const +{ + bool crontab, allUsers; + KTListItem *ktli, *user; + + const CTHost& cth(ktapp->getCTHost()); + + KTPrint printer(cth.root()); + + if (printer.start()) + { + crontab = printer.crontab(); + allUsers = printer.allUsers(); + + printer.createColumns(3); + + int copies = printer.numCopies(); + while (copies != 0) + { + if (allUsers || !cth.root()) + { + ktli = (KTListItem*)listView->firstChild(); + } + else + { + ktli = (KTListItem*)listView->currentItem(); + } + + //Check that the correct item is selected, they must + //select the top level entry for all items to print + while (ktli->depth() != 0) + ktli = (KTListItem*)ktli->parent(); + + user = ktli; //Used to store user's name + + if (allUsers) + { + while (ktli) + { + pageHeading(ktli, printer); + ktli->print(printer); + if (crontab) + pageFooter(ktli, printer); + ktli = (KTListItem*)ktli->nextSibling(); + if (ktli) + printer.newPage(); + } + } + else + { + //ktli goes out of range here hence the need for user + pageHeading(user, printer); + if (!cth.root()) + { + while (ktli) + { + ktli->print(printer); + ktli = (KTListItem*)ktli->nextSibling(); + } + } + else + ktli->print(printer); + + if (crontab) + pageFooter(user, printer); + + } + + copies--; //Keep a track of how many copies we have printed + if (copies != 0) printer.newPage(); + }//End printing loop (for more than one copy) + + printer.finished(); //End the print + + }//End Printing if +} + +void KTView :: pageHeading (KTListItem* user, KTPrint &printer) const +{ + QFont stnd; + QString logonInfo; + QDateTime now (QDateTime::currentDateTime()); + char hostName[20]; + + gethostname(hostName, 20); + // SSA : Fix Me user name, logon name and host name musst be + // SSA : not only in us-ascii ?? + logonInfo = i18n("user on host", "%1 <%2> on %3") + .arg(QString::fromLocal8Bit(user->getCTCron()->name.c_str())) + .arg(QString::fromLocal8Bit(user->getCTCron()->login.c_str())) + .arg(QString::fromLocal8Bit(hostName)); + + stnd = printer.getFont(); + printer.setFont(QFont( KGlobalSettings::generalFont().family(), 14, QFont::Bold )); + + printer.print (i18n("Scheduled Tasks"), 2, KTPrint::alignTextCenter, false); + printer.print (logonInfo, 2, KTPrint::alignTextCenter, false); + printer.print (KGlobal::locale()->formatDateTime(now), 2, KTPrint::alignTextCenter, false); + printer.setFont(stnd); + + printer.levelColumns(20); + +} + +void KTView :: pageFooter (KTListItem* user, KTPrint &printer) const +{ +#ifdef HAVE_SSTREAM + ostringstream oss; +#else + char buffer[4096]; + ostrstream oss(buffer, sizeof(buffer)); +#endif + + oss<<*(user->getCTCron())<<ends; + + if (oss) { + string crontab(oss.str()); + printer.print(crontab.c_str(), 1, KTPrint::alignTextLeft, false); + } +} + +KTView::~KTView() +{ + delete listView; +} + +void KTView::resizeEvent (QResizeEvent*) +{ + listView->setFixedWidth(width()); + listView->setFixedHeight(height()); + repaint(); +} + +void KTView::copy() +{ + if (clipboardCTTask) + { + delete clipboardCTTask; + clipboardCTTask = 0; + } + + if (clipboardCTVariable) + { + delete clipboardCTVariable; + clipboardCTVariable = 0; + } + + if (currentIsTask) + { + clipboardCTTask = new CTTask(*currentCTTask); + } + else + { + clipboardCTVariable = new CTVariable(*currentCTVariable); + } + clipboardIsTask = currentIsTask; +} + +void KTView::paste() +{ + KTListItem* qlvi = (KTListItem*)listView->currentItem(); + + if (currentIsTask) + { + CTTask* temptask = new CTTask(*clipboardCTTask); + currentCTCron->task.push_back(temptask); + KTListTask* ktlt = new KTListTask(qlvi, currentCTCron, temptask); + listView->setSelected(ktlt, true); + } + else + { + CTVariable* tempvar = new CTVariable(*clipboardCTVariable); + currentCTCron->variable.push_back(tempvar); + KTListVar* ktlv = new KTListVar(qlvi, currentCTCron, tempvar); + listView->setSelected(ktlv, true); + } +} + +void KTView::create() +{ + KTListItem* ktli = (KTListItem*)listView->currentItem(); + if ((ktli->text(0) != KTListTasks::getDescription()) && (ktli->text(0) != KTListVars::getDescription())) { + ktli = (KTListItem*)ktli->parent(); + } + Q_CHECK_PTR(ktli); + ktli->create(); + listView->triggerUpdate(); +} + +void KTView::edit() +{ + KTListItem* ktli = (KTListItem*)listView->currentItem(); + Q_CHECK_PTR(ktli); + ktli->edit(); + listView->triggerUpdate(); +} + +void KTView::remove() +{ + if (currentIsTask) + { + if (currentCTTask) + { + for (CTTaskIterator i = (CTTaskIterator) + (currentCTCron->task.begin()); + i != currentCTCron->task.end(); i++) + { + if (*i == currentCTTask) + { + currentCTCron->task.erase(i); + delete currentCTTask; + currentCTTask = 0; + break; + } + } + } + } + else + { + if (currentCTVariable) + { + for (CTVariableIterator j = (CTVariableIterator) + (currentCTCron->variable.begin()); + j != currentCTCron->variable.end(); j++) + { + if (*j == currentCTVariable) + { + currentCTCron->variable.erase(j); + delete currentCTVariable; + currentCTVariable = 0; + break; + } + } + } + } + refresh(); +} + +QString KTView::absolute() const +{ + QString fullCommand = QString::fromLocal8Bit(currentCTTask->command.c_str()); + QString command(fullCommand); + int pos(command.find(" ")); + if (pos > 0) command = command.left(pos); + + if (command.find("/") == 0) + return fullCommand; + + QString path = QString::fromLocal8Bit(currentCTCron->path().c_str()); + int begin(0); + int end(0); + QString prefix; + QString full; + + while ((end = path.find(":", begin)) > 0) + { + prefix = path.mid(begin, begin + end) + "/"; + full = prefix + command; + if (QFileInfo(full).isExecutable()) + return QString(prefix + fullCommand); + begin = end + 1; + } + prefix = path.mid(begin, begin + end) + "/"; + full = prefix + command; + if (QFileInfo(full).isExecutable()) + return QString(prefix + fullCommand); + return QString(""); +} + +void KTView::run() const +{ + QString command(absolute() + " &"); + system(QFile::encodeName(command)); +} + +void KTView::enable(bool enable) +{ + QListViewItem* qlvi = listView->currentItem(); + + if (currentIsTask) + { + if (currentCTTask) + { + currentCTTask->enabled = enable; + ((KTListTask*)(qlvi))->refresh(); + } + } + else + { + if (currentCTVariable) + { + currentCTVariable->enabled = enable; + ((KTListVar*)(qlvi))->refresh(); + } + } +} + +void KTView::slotMenu(QListViewItem* qlvi, const QPoint& qp, int /*i*/) +{ + if (qlvi !=0 ) { + listView->setSelected(qlvi, true); + slotSetCurrent(qlvi); + ktapp->slotEdit(qp); + } +} + +void KTView::slotEdit(QListViewItem* /*qlvi*/) +{ + edit(); +} + +void KTView::slotSetCurrent (QListViewItem* qlvi) +{ + QListViewItem* parent = qlvi->parent(); + + if (qlvi->text(0) == KTListVars::getDescription()) + { + // variable label + currentCTCron = ((KTListCron*)qlvi)->getCTCron(); + currentCTVariable = 0; + currentCTTask = 0; + currentIsTask = false; + emit(enableModificationButtons(false)); + emit(enablePaste(clipboardCTVariable)); + emit(enableRunNow(false)); + emit(enableEnabled(false)); + + } + else if (qlvi->text(0) == KTListTasks::getDescription()) + { + // task label + currentCTCron = ((KTListCron*)qlvi)->getCTCron(); + currentCTVariable = 0; + currentCTTask = 0; + currentIsTask = true; + + emit(enableModificationButtons(false)); + emit(enablePaste(clipboardCTTask)); + emit(enableRunNow(false)); + emit(enableEnabled(false)); + + } + else if (parent) + { + if (parent->text(0) == KTListVars::getDescription()) + { + // variable + currentCTCron = ((KTListVar*)qlvi)->getCTCron(); + currentCTVariable = ((KTListVar*)qlvi)->getCTVariable(); + currentCTTask = 0; + currentIsTask = false; + + emit(enableModificationButtons(true)); + emit(enableRunNow(false)); + emit(enableEnabled(currentCTVariable->enabled)); + + } + else if (parent->text(0) == KTListTasks::getDescription()) + { + // task + currentCTCron = ((KTListTask*)qlvi)->getCTCron(); + currentCTVariable = 0; + currentCTTask = ((KTListTask*)qlvi)->getCTTask(); + currentIsTask = true; + + emit(enableModificationButtons(true)); + emit(enableRunNow((currentCTTask->enabled) && + (!absolute().isEmpty()))); + emit(enableEnabled(currentCTTask->enabled)); + + } + } + else + { + // user + currentCTCron = ((KTListCron*)qlvi)->getCTCron(); + currentCTVariable = 0; + currentCTTask = 0; + currentIsTask = true; + + emit(enableModificationButtons(true)); + emit(enablePaste(false)); + emit(enableRunNow(false)); + emit(enableEnabled(false)); + + } +} + +#include "ktview.moc" diff --git a/kcron/ktview.h b/kcron/ktview.h new file mode 100644 index 0000000..e25129a --- /dev/null +++ b/kcron/ktview.h @@ -0,0 +1,215 @@ +/*************************************************************************** + * KT main view header. * + * -------------------------------------------------------------------- * + * Copyright (C) 1999, Gary Meyer <gary@meyer.net> * + * -------------------------------------------------------------------- * + * 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. * + ***************************************************************************/ + +#ifndef KTVIEW_H +#define KTVIEW_H + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <qwidget.h> + +class QString; +class QListView; +class QListViewItem; +class KTApp; +class KTPrint; +class KTListItem; +class CTCron; +class CTVariable; +class CTTask; + +/** + * Main GUI view of the crontab entries. + */ +class KTView : public QWidget +{ + Q_OBJECT + +public: + +/** + * Initializes view. + */ + KTView (QWidget* parent = 0, const char* name=0); + +/** + * Destructor. + */ + ~KTView(); + +/** + * Print crontab. + */ + void print() const; + +/** + * Print page heading. + */ + void pageHeading (KTListItem *user, KTPrint &printer) const; + +/** + * Print page footer. + */ + void pageFooter (KTListItem *user, KTPrint &printer) const; + +/** + * Copies variables and/or tasks. + */ + void copy(); + +/** + * Pastes variables and/or tasks from the clipboard. + */ + void paste(); + +/** + * Create a new variable or task. Default is which type is most recently + * selected. + */ + void create(); + +/** + * Edit variable or task. Default is most recently selected. + */ + void edit(); + +/** + * Delete variables and/or tasks. + */ + void remove(); + +/** + * Enables/disables variables and/or tasks. + */ + void enable(bool enable = true); + +/** + * Run task now. + */ + void run() const; + +/** + * Disable selected icons + */ + void disableIcons(); + +signals: + +/** Enables/disables modification + * buttons depending + * on if a task is selected + */ + void enableModificationButtons(bool); + +/** Enables/disables paste button depending + * on clipboard contents + */ + void enablePaste(bool); + +/** Enables/disables "Run now" depending + * on the task settings + */ + void enableRunNow(bool); + +/** Enables/disables "Activated" setting + * on the menu depending on the task + * configuration + */ + void enableEnabled(bool); + +public slots: + +/** + * Pop up context sensitive menu. + */ + void slotMenu(QListViewItem* qlvi, const QPoint& qp, int i); + +/** + * Default action, edit. + */ + void slotEdit(QListViewItem* qlvi = 0); + +protected slots: + +/** + * Set current and update menu + */ + void slotSetCurrent (QListViewItem* qlvi); + +protected: + +/** + * Resize view contents. + */ + virtual void resizeEvent (QResizeEvent* = 0); + +private: + +/** + * Get absolute path of command. + */ + QString absolute() const; + +/** + * Refresh view from underlying objects. + */ + void refresh(); + +/** + * The application. + */ + KTApp* ktapp; + +/** + * Tree view of the crontab entries. + */ + QListView* listView; + +/** + * Current user's crontab. + */ + CTCron* currentCTCron; + +/** + * Indicates whether or not currently selected item is a task. + */ + bool currentIsTask; + +/** + * Current task. + */ + CTTask* currentCTTask; + +/** + * Current variable. + */ + CTVariable* currentCTVariable; + +/** + * Indicates whether or not the item on the clipboard is a task. + */ + bool clipboardIsTask; + +/** + * Clipboard task. + */ + CTTask* clipboardCTTask; + +/** + * Clipboard variable. + */ + CTVariable* clipboardCTVariable; + +}; + +#endif // KTVIEW_H diff --git a/kcron/main.cpp b/kcron/main.cpp new file mode 100644 index 0000000..b77ec27 --- /dev/null +++ b/kcron/main.cpp @@ -0,0 +1,47 @@ +/*************************************************************************** + * Main. * + * -------------------------------------------------------------------- * + * Copyright (C) 1999, Gary Meyer <gary@meyer.net> * + * -------------------------------------------------------------------- * + * 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. * + ***************************************************************************/ + +#include <kapplication.h> +#include <klocale.h> +#include "ktapp.h" +#include <kcmdlineargs.h> +#include <kaboutdata.h> + +int main(int argc, char* argv[]) +{ + static const char description[] = I18N_NOOP("KDE Task Scheduler"); + + KAboutData aboutData("kcron", I18N_NOOP("KCron"), + VERSION, description, KAboutData::License_GPL, + "(c) 1999-2000, Gary Meyer"); + + aboutData.addAuthor("Gary Meyer", 0, "gary@meyer.net"); + aboutData.addAuthor("Robert Berry", 0, "rjmber@ntlworld.com"); + aboutData.addAuthor("James Ots", 0, "code@jamesots.com"); + aboutData.addAuthor("Alberto G. Hierro", 0, "alberto.hierro@kdemail.net"); + + KCmdLineArgs::init(argc, argv, &aboutData); + + KApplication app; + + if (app.isRestored()) + { + RESTORE(KTApp); + } + else + { + KTApp* kcron = new KTApp; + if (!kcron->init()) + return 1; + kcron->show(); + } + return app.exec(); +} |