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 | 2bda8f7717adf28da4af0d34fb82f63d2868c31d (patch) | |
tree | 8d927b7b47a90c4adb646482a52613f58acd6f8c /ksim | |
download | tdeutils-2bda8f7717adf28da4af0d34fb82f63d2868c31d.tar.gz tdeutils-2bda8f7717adf28da4af0d34fb82f63d2868c31d.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/kdeutils@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'ksim')
183 files changed, 25765 insertions, 0 deletions
diff --git a/ksim/AUTHORS b/ksim/AUTHORS new file mode 100644 index 0000000..ceef583 --- /dev/null +++ b/ksim/AUTHORS @@ -0,0 +1,2 @@ +Robbie Ward <linuxphreak@gmx.co.uk> +Jason Katz-Brown <jason@katzbrown.com> diff --git a/ksim/BUGS b/ksim/BUGS new file mode 100644 index 0000000..8a3e620 --- /dev/null +++ b/ksim/BUGS @@ -0,0 +1,3 @@ +Current known bugs (as of 1.1.0): + + * see bugs.kde.org diff --git a/ksim/COPYING b/ksim/COPYING new file mode 100644 index 0000000..37ba36f --- /dev/null +++ b/ksim/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/ksim/ChangeLog b/ksim/ChangeLog new file mode 100644 index 0000000..837a287 --- /dev/null +++ b/ksim/ChangeLog @@ -0,0 +1,363 @@ +KSim 1.1.0: + +Bug/Feature Changes: + * KSim no longer needs to generate gkrellmrc_ksim files, KSim will keep + the parsed file in memory + * Save the "on all desktop settings" when ksim is minimised + * Fixed the crash in the sensors plugin when using lm_sensors 2.7.0 + * Rewrote the CPU plugin, this should fix the problems with smp systems + * Made KSim a Kicker extension + * Made the configuration pages more user friendly + * Dont display filesystems if the block size is zero + * Fixed unsaved checked / unchecked items in the filesystem plugin being + removed when the configuration page is redisplayed + +API Changes: + * None + + -- Robbie Ward <wardy@robbieward.co.uk> + +KSim 1.0.0: + +Bug/Feature Changes: + * Fixed a crash in ksim_disk when using FreeBSD + * Fixed the odd crash when ok or close is clicked in the config + dialog + * Added checks to fix compile issues on older kernel versions + * Some compile fixes for certain platforms + * Fixed a crash in KSim::ThemeLoader which occurred when + the theme alternative was set to a higher value than it should + * Fixed rare crashes in KSim::Led + +API Changes: + * No need to reimplement sizePolicy() in KSim::Label + and KSim::Chart + * Fixed spelling mistakes in the API + + -- Robbie Ward <linuxphreak@gmx.co.uk> Saturday 02 November 2002 + +KSim 0.9.0: + +Bug/Feature Changes: + * Added checkbox to turn on / off the FQDN option + * Display the data in the net, cpu and disk plugins when + they get loaded + * Small cpu usage fix in the net plugin + * Added the option to recolour themes to the current + KDE color scheme + * Less expensive masking routines for the leds, and a less + expensive background drawing routine for labels + * The disk plugin is now able to monitor multiple disks + * Fixed the problem with the mininum width not being set + correctly in the filesystem when some entries were long + * Only remove a net device from the net plugin configuration + page when the apply button is clicked + * Remove partitions from the filesystem configuration page if + any partitions have been unmounted + +API Changes: + * Made the function names in KSim::Theme more consistant + * Moved setMinValue(), setMaxValue(), setValue() and setTitle() + from public to public slots in KSim::Chart + * Made KSim::ThemeLoader::currentTheme() a reference rather + than a pointer and renamed it to current() + * Renamed *Module() to *Plugin() in KSim::PluginLoader + * Renamed KSim::ThemeLoader::currentTheme*() to current*() + * Moved KSim::Label::setType() from protected to public + * Renamed KSim::ThemeLoader::parseThemeDir to parseDir + * Renamed KSim::ThemeLoader::themeAltString() to alternativeAsString() + * Made KSim::ThemeLoader::pargeConfig() and parseDir() static + * Renamed the KSim::ThemeLoader::ImageType enum to PixmapType + * Added some functions to KSim::Chart, KSim::Progress + and KSim::LedLabel + + -- Robbie Ward <linuxphreak@gmx.co.uk> Wednesday 05 June 2002 + +KSim 0.8.1: + +Bug/Feature Changes: + * Fixed the bug in KSim::Label which sometimes prevented setText() + from updatig the display, the clock and uptime was affected by this + +API Changes: + * None + + -- Robbie Ward <linuxphreak@gmx.co.uk> Monday 20 May 2002 + +KSim 0.8.0: + +Bug/Feature Changes: + * Make the filesystem plugin compile on Solaris + * Fixed the exec command option + * Fixed the SMP bug in the cpu plugin + * Build fixes in the cpu plugin for OpenBSD + * Added the option to display a short version of a mount point in + the filesystem plugin + * Fixed the problem with the progress meters not working sometimes + * Added the option to not display a FQDN, no GUI config option + at this time. To enable add 'DisplayFqdn=false' to ksimrc under + the '[Misc]' section + +API Changes: + * Added some new functions to KSim::Led + * Be consistant with the way the word 'Colour' is used in function names + * Added a KSim::Theme::currentFont() function which returns the + font KSim should use according to fontItem(); + * Renamed KSim::Led::setImage to setPixmap + * Remember to update the geometry so the layout can get a new sizeHint() + * Renamed setThemeImage to setThemePixmap and + setMeterImage to setThemePixmap + * Let KSim handle the config()->sync() call rather than the plugins + * Added a non-const version of KSim::PluginLoader::pluginList() + * Added a KSim::PluginLoader::plugin() function which returns + the last plugin loaded (or a null plugin if one couldnt be loaded) + * Also added a non-const version of KSim::PluginLoader::plugin() + * Renamed splitImage to splitPixmap in KSim::Theme + * Added a KSim::Theme::pixmapToList function + * Changed KSim::Chart::text() to accept a KSim::Chart::DataType + enum rather than an int + * Make the second parameter in KSim::Chart::setValue() have a + default value + * Added a new constructor to KSim::Progress + * Added a new constructor to KSim::LedLabel + * Document the KSim::PluginInfo class + * Append "ksim_" to the config filename for the plugins + * Added an extra SearchType to KSim::PluginLoader::findPlugin() + called LibName + + -- Robbie Ward <linuxphreak@gmx.co.uk> Saturday 11 May 2002 + +KSim 0.7.0: + +Bug/Feature Changes: + * Display an error message if a network interface is added + which is already in the listview + * Disable the speed spin box if the stack items checkbox is not + ticked in the filesystem plugin config page + * Cleaned up the filesystem plugin config page GUI a little + * Cleaned up the sensors plugin config page GUI a little + * Some text / word corrections and spelling corrections + * Update the disk plugin display asap if anything has changed + * Dont set the hours, minutes and seconds time in the net plugin + if they are an invalid time format + * Update the memory and swap text labels when KSim reloads its + configuration rather than doing it 5 seconds later + * Dont increase the size of the filesystem view every time a + filesystem display is added or removed + * Pevent the net plugin from showing wacko in and out values + when a net interface is added or removed + * Prevent KSim from increasing size by 1 or 2 pixels when KSim + reloads its configuration + * Fixed the filesystem plugin view resizing to the wrong width when + an item is added + * Fixed the very weird problem where the led label and the normal + label would appear above the graphs for some people + * Fixed the bug where KSim would be resized to a very large width + when the net plugin was loaded after KSim had started + * Dont wait a second before we display the uptime and clock text + at KSim startup + * Fixed the problem with the filesystem plugin not being set to the + correct width sometimes when the plugin was loaded + * Fixed the bug where KSim would sometimes not be resize itself + to the correct height due to a bug in the filesystem plugin + * Added check for getloadavg() for some systems that dont have + this function + * Set the minimum width to the smallest possible rather than + hardcoding it to 80 pixels + * Dont store the enabled/disabled plugin as the translated plugin + name but the library name instead + * Relayout the leds correctly in KSim::LedLabel on theme change + +API Changes: + * Added a 'KSim::Theme::splitImage(ImageType type, bool useDefault)' + function + * Added two new functions to KSim::PluginObject which are + 'void setConfigFileName(const QString &)' and + 'const QString &configFileName()' + * Make the singleton instances return a reference rather than a + pointer to prevent accidental deletion + * Made the cleanup() functions in KSim::PluginLoader and + KSim::ThemeLoader private, so only the core of KSim can + cleanup these classes and nothing else + * Added a KSim::PluginLoader::findPlugin() method, which finds + out various plugin information from the string you give it + + -- Robbie Ward <linuxphreak@gmx.co.uk> Saturday 27 April 2002 + +KSim 0.6.1: + +Bug/Feature Changes: + * Correctly set the default krell depth value so some themes dont show + the whole image as the meter/panel + * Only show the first part of the image rather than the whole image when + the progress bars are told to display krell_meter.png + * Dont forget to create the LED masks if needed + * Some FreeBSD build fixes in the net and disk plugins + * Fixed a recursive looping crash when there was no KSim config file + +API Changes: + * None + + -- Robbie Ward <linuxphreak@gmx.co.uk> Tuesday 16 April 2002 + +KSim 0.6.0: + +Bug/Feature Changes: + * Added a modify button on the net configuration page + * Dont store absolute paths in the theme configuration, so if one + moves their kdedir to somewhere else then they wont have to + change any configuration settings + * Display a more correct value of the free ram on linux + * Fixed the bug where some themes would prevent any + data being drawn onto the graphs + * Reload the config page settings when the close button + is clicked in the config dialog + * Keep any changes in the sensor config listview unless + the apply/ok/close buttons are clicked in the config dialog + * Fixed the crash when enabling the clock, date, uptime, + memory or swap displays + * Fixed the charts not being resized when KSim reloads its + configuration + * Correcly show/hide the systray on configuration reload + * Correcly check/uncheck the always on top menu item if + the config option has changed + * Keep any changes in the filesystem config listview unless + the apply/ok/close buttons are clicked in the config dialog + +API Changes: + * Added a bool isThemeOnly() function in KSim::Base + which tells KSim if this KSim::Base instance should + have configureObject() called even if the theme hasn't + changed + + -- Robbie Ward <linuxphreak@gmx.co.uk> Sunday 14 April 2002 + +KSim 0.5.1: + +Bug/Feature Changes: + * Added uptime and clock icons for the config dialog + * Fixed the problem when KSim would resize to 0 when the + apply button is clicked + * Removed the nice checkbox from the cpu config page and + added a new cpu key (%T which is user + sys + nice) + * Correcly set the filesystem height on plugin reloading if the + stack items checkbox is ticked + * Fixed the problem of the list view not being cleared in the + sensors plugin when the config dialog closes + +API Changes: + * None + + -- Robbie Ward <linuxphreak@gmx.co.uk> Thursday 28 March 2002 + +KSim 0.5: + +Bug/Feature Changes: + * Added Disk monitor plugin + * Added Mail monitor plugin (written by Malte Starostik) + * Worked around the leak in the sensors plugin + * Set the backgrounds of widgets correctly if UseThemes is set to false + * Changed the combo boxes in the add net dialog to url requesters + * Fixed the ASSERT warnings when the sensors plugin is initially configured + * Fixed the problems in the net plugin where there was a slight chance + the net device name (for the add net dialog) could contain the receive + bytes or the receive bytes data (for the main plugin) could contain the + net device also + * Speed improvement: dont recreate a plugins view if it is about to be + removed or if it was just loaded + * Remember to set the current text in the net dialog when you + double click on a net interface in the listview + * Display a "Are you sure you want to remove this net interface?" + message box when you ask KSim to remove the currently selected + net interface in the list view + +API Changes: + * Added a krellMail(bool = false) function in themeloader.h + * moved all the theme functions from common.h to themeloader.h + * Try and return an optional default value for the themeloader if the value + isnt found and then return the value for the default theme if that + also is invalid + + -- Robbie Ward <linuxphreak@gmx.co.uk> Tuesday 26 March 2002 + +KSim 0.4: + +Bug/Feature Changes: + * Fixed the resize delay in the filesystem plugin + * Fixed segfault when KSim was started with an invalid 'themeUrl' entry + * Fixed compile problems on FreeBSD in the net plugin + * Ported the cpu plugin to OpenBSD and NetBSD + * Reduced flicker in the led labels + * More theme enhancements + * Faster theme loading times + * Dont move KSim to the location stored in the config file if the systray + icon hides and then later shows KSim's main view + * Stop the cpu plugin from updating when it reloads its configuration, + and then resume the updating once finished to avoid crashes + * Improved the speed/memory usage of the sensors plugin when + you are displaying many sensor labels + * Dont attempt to unload all plugins and then crash if there was a problem + loading a plugin when KSim starts up + * Update the listviews in the sensors and filesystem config pages when + the config page gets displayed and hidden + +API Changes: + * Return a null string if we cant open the theme's gkrellmrc + file in ThemeLoader::parseConfig() + * Completely removed the first arg in KSIM_INIT_PLUGIN() + * Removed the 'ksim' prefix from the installed headers (eg: ksimblah is + now blah.h), this only affects people who write plugins as + eg '#include <ksim/ksimlabel.h>' will become '#include <ksim/label.h> + + -- Robbie Ward <linuxphreak@gmx.co.uk> Tuesday 05 March 2002 + +KSim 0.3: + + * Added CPU plugin + * Implemented more theme support + * Improved the performance and cleaned up the code in the net plugin + * Decode the filenames to Unicode when using the command line options + * Fixed the adding/removing interfaces problem in the net plugin + * Made the first arg in KSIM_INIT_PLUGIN() redundant + * Some speed/memory fixes + * Moved the misc config page to seperate pages in the config dialog + * Fixed the plugin reloading issues in the net, sensors and filesystem plugins + * Workaround fix for the expensiveness of colecting the meminfo on FreeBSD + * Added time/date display (patch from Heitham Omar) + * Fixed some leaks in the net/sensors/filesystem plugins + * Moved the two enums from KSim::Theme to KSim::Types + * Fixed various themeing issues + * Fixed various spelling mistakes + * Reset the net-plugin information to zero when a net interface goes off line + * Insert the available net interfaces into the add net interface dialog + * Fixed the bug where some themes (one without masked image borders) + would influence if KSim had a kwin deco or not + * Re-worked the KSim::Base class, a derived class of KSim::Base no + longer has to inherit a QObject derived class and doesn't have to + reimplement 'void setName(const char *name)' + + -- Robbie Ward <linuxphreak@gmx.co.uk> Wednesday 13 February 2002 + +KSim 0.2: + + * Re-Wrote the Plugin/PluginLoader code + * Re-Wrote the ThemeLoader code + * Fixed various memleaks + * Implemented the graph widget + * Correctly collect the in/out net data + * Fixed various problems on FreeBSD + * Some speed improvements + * Other tweaks/fixes to the code + * Moved the remainder of the API to a KSim namespace + * Fixed errors with building plugins outside of KSim + * Made X-KSIM-PREFS (in the .desktop files) redundant + * Moved the set on all desktops/always on top popupmenu from + the frames of the app to the main popup menu + + -- Robbie Ward <linuxphreak@gmx.co.uk> Saturday 05 January 2002 + +KSim 0.1: + + * Initial release + + -- Robbie Ward <linuxphreak@gmx.co.uk> Thursday 28 June 2001 diff --git a/ksim/Makefile.am b/ksim/Makefile.am new file mode 100644 index 0000000..c8102cb --- /dev/null +++ b/ksim/Makefile.am @@ -0,0 +1,34 @@ +noinst_LTLIBRARIES = libsysteminfo.la + +libsysteminfo_la_SOURCES = systeminfo.cpp +libsysteminfo_la_LDFLAGS = -module -avoid-version + +kde_module_LTLIBRARIES = ksim_panelextension.la +ksim_panelextension_la_SOURCES = ksim.cpp ksimview.cpp ksimview.skel \ + ksimsysinfo.cpp ksimsysinfo.skel ksimframe.cpp \ + ksimpref.cpp monitorprefs.cpp generalprefs.cpp \ + themeprefs.cpp + +ksim_panelextension_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries) +ksim_panelextension_la_LIBADD = ./library/libksimcore.la libsysteminfo.la $(LIB_KIO) $(LIB_KDEUI) + +SUBDIRS = themes library monitors pics +EXTRA_DIST = ksim.desktop +METASOURCES = AUTO +CLEANFILES = dummy.cpp + +extension_DATA = ksim.desktop +extensiondir = $(kde_datadir)/kicker/extensions + +dummy.cpp: + echo > dummy.cpp + +INCLUDES= -I$(top_srcdir)/ksim/library \ + $(all_includes) + +conf_DATA = ksim_panelextensionrc +confdir = $(kde_confdir) + +messages: rc.cpp + $(EXTRACTRC) */*.rc */*.ui *.ui *.rc >> rc.cpp + $(XGETTEXT) `find . -name "*.cpp"` -o $(podir)/ksim.pot diff --git a/ksim/README b/ksim/README new file mode 100644 index 0000000..d5ee23a --- /dev/null +++ b/ksim/README @@ -0,0 +1,42 @@ +KSim - K System Information Monitor +----------------------------------- + +KSim is a plugin based system monitor that has +support for GKrellm (www.gkrellm.net) themes. + +KSim can currently monitor these types: + * Cpu usage (plugin) + * Net (eth0, ppp0 etc) usage (plugin) + * Filesystem usage (plugin) + * Sensors information (plugin) + * Disk information (plugin) + * Mail monitor (plugin) + * Clock & Date display + * Hostname display + * Uptime display + * Memory/Free Memory display + * Swap/Free Swap display + +The current planned features are: + * Proc monitor (plugin) + +NOTE: the plugin naming conventions changed +in v0.5 and above, i recommend you to +rm -rf $KDEDIR/lib/libksim* before you install +v0.5 or above, if you are using v0.4 or below. + +As of v0.9.0 and above, KSim has the option to +recolour themes to the current KDE color scheme, +if you have any problems of it recolouring to the wrong +color or some other recolouring related problem then +send me the name of the color scheme you are using +and the color values for your background and text color. + +Please read BUGS for a list of current known bugs +and ChangeLog for the changes in the last release. +Also the theme support isn't 100% implemented +(which it may never be), if you have any theme +related issues then please email me describing what +problem you had and with which theme. + +Any other problems? email me (linuxphreak@gmx.co.uk) diff --git a/ksim/TODO b/ksim/TODO new file mode 100644 index 0000000..f749d5b --- /dev/null +++ b/ksim/TODO @@ -0,0 +1,5 @@ +Current things todo (in any order): + + * Fix the bug in BUGS + * Insert the plugin views at the correct location and don't just append + them to the bottom of the view diff --git a/ksim/baselist.h b/ksim/baselist.h new file mode 100644 index 0000000..b55ab3b --- /dev/null +++ b/ksim/baselist.h @@ -0,0 +1,97 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#ifndef BASELIST_H +#define BASELIST_H + +#include <qptrlist.h> +#include <common.h> +#include <qapplication.h> + +namespace KSim +{ + class BaseList + { + public: + static void add(KSim::Base *object) + { + if (!m_baseList) { + m_baseList = new QPtrList<KSim::Base>; + m_baseList->setAutoDelete(false); + + // Make sure our m_baseList instance gets + // deleted when KSim exits + qAddPostRoutine(cleanup); + } + + if (!object) + return; + + m_baseList->append(object); + } + + static bool remove(KSim::Base *object) + { + if (!m_baseList) + return false; + + // Find our object and remove it from the list + if (m_baseList->findRef(object) >= 0) + return m_baseList->remove(); + + return false; + } + + static void configureObjects(bool themeChanged) + { + if (!m_baseList) + return; + + QPtrListIterator<KSim::Base> object(*m_baseList); + for (; object.current(); ++object) { + // Call processEvents() so our ui doesn't block + if (!object.current()->isThemeConfigOnly() || themeChanged) { + qApp->processEvents(); + object.current()->configureObject(true); + } + } + } + + private: + // Protect the class from being able to be created/deleted + BaseList(); + BaseList(const BaseList &); + BaseList &operator=(const BaseList &); + ~BaseList(); + + static void cleanup() + { + if (!m_baseList) + return; + + delete m_baseList; + m_baseList = 0L; + } + + static QPtrList<KSim::Base> *m_baseList; + }; + + QPtrList<KSim::Base> *BaseList::m_baseList = 0L; +} +#endif // BASELIST_H diff --git a/ksim/configure.in.in b/ksim/configure.in.in new file mode 100644 index 0000000..4ddee70 --- /dev/null +++ b/ksim/configure.in.in @@ -0,0 +1,36 @@ +AC_CHECK_FUNCS(getloadavg) + +sysinfo_check=no +case "$target" in + *-*-linux*) + sysinfo_check=yes + ;; +esac + +if test x$sysinfo_check = xyes; then + sysinfo_ok=no + AC_MSG_CHECKING(for totalhigh and totalfree in sysinfo) + AC_TRY_COMPILE( + [ + #include <linux/kernel.h> + + static void check() + { + struct sysinfo system; /* dummy sysinfo */ + int totalhigh = system.totalhigh; + int freehigh = system.freehigh; + } + ], [], + [ + sysinfo_ok=yes + AC_DEFINE_UNQUOTED(HAVE_SYSINFO_HIGH, 1, [whether we have totalhigh and freehigh]) + ]) + + AC_MSG_RESULT($sysinfo_ok) +fi + +dnl Check for dell laptop support +AM_CONDITIONAL(supports_i8k, test -f /proc/i8k) + +KDE_CHECK_HEADER(X11/extensions/extutil.h, AC_DEFINE(HAVE_EXTUTIL_H, 1, [If we have extutil.h]) have_extutil_h=yes, , ) +AM_CONDITIONAL(include_nv, test "x$have_extutil_h" = "xyes") diff --git a/ksim/generalprefs.cpp b/ksim/generalprefs.cpp new file mode 100644 index 0000000..1f3baf7 --- /dev/null +++ b/ksim/generalprefs.cpp @@ -0,0 +1,574 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#include "generalprefs.h" +#include "generalprefs.moc" + +#include <qcombobox.h> +#include <qcheckbox.h> +#include <qgroupbox.h> +#include <qlabel.h> +#include <qlineedit.h> +#include <qpushbutton.h> +#include <qtabwidget.h> +#include <qlayout.h> +#include <qtooltip.h> +#include <qpopupmenu.h> + +#include <klocale.h> +#include <kapplication.h> +#include <kcombobox.h> +#include <kdebug.h> +#include <kiconloader.h> +#include <knuminput.h> + +#include <ksimconfig.h> + +KSim::GeneralPrefs::GeneralPrefs(QWidget *parent, const char *name) + : QWidget(parent, name) +{ + m_mainLayout = new QGridLayout(this); + m_mainLayout->setSpacing(6); + + m_sizeBox = new QGroupBox(this); + m_sizeBox->setTitle(i18n("Graph Size")); + m_sizeBox->setColumnLayout(0, Qt::Horizontal); + + QGridLayout *sizeBoxLayout = new QGridLayout(m_sizeBox->layout()); + sizeBoxLayout->setSpacing(6); + + m_sizeHLabel = new QLabel(m_sizeBox); + m_sizeHLabel->setText(i18n("Graph height:")); + sizeBoxLayout->addWidget(m_sizeHLabel, 0, 0); + + m_sizeHSpin = new KIntSpinBox(m_sizeBox); + m_sizeHSpin->setValue(40); + m_sizeHSpin->setMinValue(40); + m_sizeHSpin->setMaxValue(200); + m_sizeHSpin->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, + QSizePolicy::Fixed)); + sizeBoxLayout->addWidget(m_sizeHSpin, 0, 1); + + QSpacerItem *sizeHSpacer = new QSpacerItem(20, 20, + QSizePolicy::Expanding, QSizePolicy::Minimum); + sizeBoxLayout->addItem(sizeHSpacer, 0, 2); + + m_sizeWLabel = new QLabel(m_sizeBox); + m_sizeWLabel->setText(i18n("Graph width:")); + sizeBoxLayout->addWidget(m_sizeWLabel, 1, 0); + + m_sizeWSpin = new KIntSpinBox(m_sizeBox); + m_sizeWSpin->setValue(58); + m_sizeWSpin->setMinValue(58); + m_sizeWSpin->setMaxValue(200); + m_sizeWSpin->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, + QSizePolicy::Fixed)); + sizeBoxLayout->addWidget(m_sizeWSpin, 1, 1); + + QSpacerItem *sizeWSpacer = new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + sizeBoxLayout->addItem(sizeWSpacer, 1, 2); + + m_mainLayout->addWidget(m_sizeBox, 0, 0); + QSpacerItem *boxSpacer = new QSpacerItem(20, 20, + QSizePolicy::Expanding, QSizePolicy::Minimum); + m_mainLayout->addItem(boxSpacer, 0, 1); + + m_displayFqdn = new QCheckBox(this); + m_displayFqdn->setText(i18n("Display fully qualified domain name")); + m_mainLayout->addMultiCellWidget(m_displayFqdn, 1, 1, 0, 1); + + m_recolourThemes = new QCheckBox(this); + m_recolourThemes->setText(i18n("Recolor themes to the current color scheme")); + m_mainLayout->addMultiCellWidget(m_recolourThemes, 2, 2, 0, 1); + + QSpacerItem *spacer = new QSpacerItem(20, 20, + QSizePolicy::Minimum, QSizePolicy::Expanding); + m_mainLayout->addItem(spacer, 3, 0); +} + +KSim::GeneralPrefs::~GeneralPrefs() +{ +} + +void KSim::GeneralPrefs::saveConfig(KSim::Config *config) +{ + config->setGraphSize(QSize(m_sizeWSpin->value(), m_sizeHSpin->value())); + config->setDisplayFqdn(m_displayFqdn->isChecked()); + config->setReColourThemes(m_recolourThemes->isChecked()); +} + +void KSim::GeneralPrefs::readConfig(KSim::Config *config) +{ + QSize size = config->graphSize(); + m_sizeHSpin->setValue(size.height()); + m_sizeWSpin->setValue(size.width()); + m_displayFqdn->setChecked(config->displayFqdn()); + m_recolourThemes->setChecked(config->reColourThemes()); +} + +KSim::ClockPrefs::ClockPrefs(QWidget *parent, const char *name) + : QWidget(parent, name) +{ + m_mainLayout = new QVBoxLayout(this); + m_mainLayout->setSpacing(6); + + m_timeCheck = new QCheckBox(i18n("Show time"),this); + m_mainLayout->addWidget(m_timeCheck); + m_timeCheck->setChecked(true); + + m_dateCheck = new QCheckBox(i18n("Show date"),this); + m_mainLayout->addWidget(m_dateCheck); + m_dateCheck->setChecked(true); + + QSpacerItem *spacer = new QSpacerItem(20, 20, + QSizePolicy::Minimum, QSizePolicy::Expanding); + m_mainLayout->addItem(spacer); +} + +KSim::ClockPrefs::~ClockPrefs() +{ +} + +void KSim::ClockPrefs::saveConfig(KSim::Config *config) +{ + config->setShowTime(m_timeCheck->isChecked()); + config->setShowDate(m_dateCheck->isChecked()); +} + +void KSim::ClockPrefs::readConfig(KSim::Config *config) +{ + m_timeCheck->setChecked(config->showTime()); + m_dateCheck->setChecked(config->showDate()); +} + +KSim::UptimePrefs::UptimePrefs(QWidget *parent, const char *name) + : QWidget(parent, name) +{ + m_addIcon = SmallIconSet("filenew"); + m_removeIcon = SmallIconSet("editdelete"); + + m_mainLayout = new QVBoxLayout(this); + m_mainLayout->setSpacing(6); + + m_uptimeCombo = new KComboBox(true, this); + m_uptimeCombo->setDuplicatesEnabled(false); + m_uptimeCombo->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, + QSizePolicy::Fixed)); + m_uptimeCombo->insertItem(i18n("%hh:%mm:%ss")); + m_uptimeCombo->insertItem(i18n("%dd %h:%m")); + m_uptimeCombo->insertItem(i18n("Uptime: %h:%m:%s")); + connect(m_uptimeCombo, + SIGNAL(aboutToShowContextMenu(QPopupMenu *)), + SLOT(uptimeContextMenu(QPopupMenu *))); + + m_uptimeAdd = new QPushButton(this); + m_uptimeAdd->setPixmap(SmallIcon("down")); + connect(m_uptimeAdd, SIGNAL(clicked()), SLOT(insertUptimeItem())); + QToolTip::add(m_uptimeAdd, i18n("Insert item")); + + m_uptimeCheck = new QCheckBox(this); + m_uptimeCheck->setText(i18n("Show uptime")); + m_uptimeCheck->setChecked(true); + connect(m_uptimeCheck, SIGNAL(toggled(bool)), + m_uptimeCombo, SLOT(setEnabled(bool))); + connect(m_uptimeCheck, SIGNAL(toggled(bool)), + m_uptimeAdd, SLOT(setEnabled(bool))); + m_mainLayout->addWidget(m_uptimeCheck); + + m_subLayout = new QHBoxLayout; + m_subLayout->setSpacing(6); + + m_formatLabel = new QLabel(this); + m_formatLabel->setText(i18n("Uptime format:")); + m_subLayout->addWidget(m_formatLabel); + + m_subLayout->addWidget(m_uptimeCombo); + m_subLayout->addWidget(m_uptimeAdd); + m_mainLayout->addLayout(m_subLayout); + + m_uptimeInfo = new QLabel(this); + m_uptimeInfo->setText(i18n("The text in the edit box will be " + "what is displayed as \nthe uptime except the % items " + "will be replaced with \nthe legend")); + m_mainLayout->addWidget(m_uptimeInfo); + + m_uptimeBox = new QGroupBox(this); + m_uptimeBox->setTitle(i18n("Uptime Legend")); + m_uptimeBox->setColumnLayout(0, Qt::Vertical); + m_uptimeBox->layout()->setSpacing(0); + m_uptimeBox->layout()->setMargin(0); + m_boxLayout = new QVBoxLayout(m_uptimeBox->layout()); + m_boxLayout->setAlignment(Qt::AlignTop); + m_boxLayout->setSpacing(6); + m_boxLayout->setMargin(11); + + m_udLabel = new QLabel(m_uptimeBox); + m_udLabel->setText(i18n("%d - Total days uptime")); + m_boxLayout->addWidget(m_udLabel); + + m_uhLabel = new QLabel(m_uptimeBox); + m_uhLabel->setText(i18n("%h - Total hours uptime")); + m_boxLayout->addWidget(m_uhLabel); + + m_umLabel = new QLabel(m_uptimeBox); + m_umLabel->setText(i18n("%m - Total minutes uptime")); + m_boxLayout->addWidget(m_umLabel); + + m_usLabel = new QLabel(m_uptimeBox); + m_usLabel->setText(i18n("%s - Total seconds uptime")); + m_boxLayout->addWidget(m_usLabel); + m_mainLayout->addWidget(m_uptimeBox); + + QSpacerItem *spacer = new QSpacerItem(20, 20, + QSizePolicy::Minimum, QSizePolicy::Expanding); + m_mainLayout->addItem(spacer); +} + +KSim::UptimePrefs::~UptimePrefs() +{ +} + +void KSim::UptimePrefs::saveConfig(KSim::Config *config) +{ + config->setUptimeItem(m_uptimeCombo->currentItem()); + config->setShowUptime(m_uptimeCheck->isChecked()); + + QStringList comboItems; + for (int i = 0; i < m_uptimeCombo->count(); i++) + comboItems.append(m_uptimeCombo->text(i)); + + config->setUptimeFormat(comboItems); +} + +void KSim::UptimePrefs::readConfig(KSim::Config *config) +{ + m_uptimeCheck->setChecked(config->showUptime()); + + QStringList::ConstIterator it; + QStringList items = config->uptimeFormatList(); + for (it = items.begin(); it != items.end(); ++it) + if (!m_uptimeCombo->contains(*it)) + m_uptimeCombo->insertItem(*it); + + m_uptimeCombo->setCurrentItem(config->uptimeItem()); +} + +void KSim::UptimePrefs::uptimeContextMenu(QPopupMenu *menu) +{ + menu->insertSeparator(); + menu->insertItem(m_addIcon, i18n("Insert Item"), + this, SLOT(insertUptimeItem())); + menu->insertItem(m_removeIcon, i18n("Remove Item"), + this, SLOT(removeUptimeItem())); +} + +void KSim::UptimePrefs::insertUptimeItem() +{ + QString text = m_uptimeCombo->lineEdit()->text(); + if (!m_uptimeCombo->contains(text)) { + m_uptimeCombo->insertItem(text); + m_uptimeCombo->setCurrentItem(m_uptimeCombo->count() - 1); + } +} + +void KSim::UptimePrefs::removeUptimeItem() +{ + int currentItem = m_uptimeCombo->currentItem(); + m_uptimeCombo->removeItem(currentItem); + m_uptimeCombo->setCurrentItem(currentItem - 1); +} + +KSim::MemoryPrefs::MemoryPrefs(QWidget *parent, const char *name) + : QWidget(parent, name) +{ + m_addIcon = SmallIconSet("filenew"); + m_removeIcon = SmallIconSet("editdelete"); + + m_mainLayout = new QVBoxLayout(this); + m_mainLayout->setSpacing(6); + + m_memCombo = new KComboBox(true, this); + m_memCombo->setDuplicatesEnabled(false); + m_memCombo->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, + QSizePolicy::Fixed)); + //m_memCombo->insertItem(i18n("%tM - %fM free")); + //m_memCombo->insertItem(i18n("%tM - %uM used")); + connect(m_memCombo, + SIGNAL(aboutToShowContextMenu(QPopupMenu *)), + SLOT(memoryContextMenu(QPopupMenu *))); + + m_memoryAdd = new QPushButton(this); + m_memoryAdd->setPixmap(SmallIcon("down")); + connect(m_memoryAdd, SIGNAL(clicked()), SLOT(insertMemoryItem())); + QToolTip::add(m_memoryAdd, i18n("Insert item")); + + m_memCheck = new QCheckBox(this); + m_memCheck->setText(i18n("Show memory and free memory")); + m_memCheck->setChecked(false); + connect(m_memCheck, SIGNAL(toggled(bool)), + m_memCombo, SLOT(setEnabled(bool))); + connect(m_memCheck, SIGNAL(toggled(bool)), + m_memoryAdd, SLOT(setEnabled(bool))); + m_mainLayout->addWidget(m_memCheck); + + m_subLayout = new QHBoxLayout; + m_subLayout->setSpacing(6); + + m_memFormat = new QLabel(this); + m_memFormat->setText(i18n("Mem format:")); + m_subLayout->addWidget(m_memFormat); + + m_subLayout->addWidget(m_memCombo); + m_subLayout->addWidget(m_memoryAdd); + m_mainLayout->addLayout(m_subLayout); + + m_memInfo = new QLabel(this); + m_memInfo->setText(i18n("The text in the edit box will be what " + "is displayed as \nthe memory & free memory except the " + "% items will be \nreplaced with the legend")); + m_mainLayout->addWidget(m_memInfo); + + m_memBox = new QGroupBox(this); + m_memBox->setTitle(i18n("Memory Legend")); + m_memBox->setColumnLayout(0, Qt::Vertical); + m_memBox->layout()->setSpacing(0); + m_memBox->layout()->setMargin(0); + m_boxLayout = new QVBoxLayout(m_memBox->layout()); + m_boxLayout->setAlignment(Qt::AlignTop); + m_boxLayout->setSpacing(6); + m_boxLayout->setMargin(11); + + m_mtLabel = new QLabel(m_memBox); + m_mtLabel->setText(i18n("%t - Total memory")); + m_boxLayout->addWidget(m_mtLabel); + + m_mfLabel = new QLabel(m_memBox); + m_mfLabel->setText(i18n("%F - Total free memory including cached and buffered")); + m_boxLayout->addWidget(m_mfLabel); + + m_mfLabel = new QLabel(m_memBox); + m_mfLabel->setText(i18n("%f - Total free memory")); + m_boxLayout->addWidget(m_mfLabel); + + m_muLabel = new QLabel(m_memBox); + m_muLabel->setText(i18n("%u - Total used memory")); + m_boxLayout->addWidget(m_muLabel); + + m_mcLabel = new QLabel(m_memBox); + m_mcLabel->setText(i18n("%c - Total cached memory")); + m_boxLayout->addWidget(m_mcLabel); + + m_mbLabel = new QLabel(m_memBox); + m_mbLabel->setText(i18n("%b - Total buffered memory")); + m_boxLayout->addWidget(m_mbLabel); + + m_msLabel = new QLabel(m_memBox); + m_msLabel->setText(i18n("%s - Total shared memory")); + m_boxLayout->addWidget(m_msLabel); + m_mainLayout->addWidget(m_memBox); + + QSpacerItem *spacer = new QSpacerItem(20, 20, + QSizePolicy::Minimum, QSizePolicy::Expanding); + m_mainLayout->addItem(spacer); +} + +KSim::MemoryPrefs::~MemoryPrefs() +{ +} + +void KSim::MemoryPrefs::saveConfig(KSim::Config *config) +{ + config->setMemoryItem(m_memCombo->currentItem()); + config->setShowMemory(m_memCheck->isChecked()); + + QStringList comboItems; + for (int i = 0; i < m_memCombo->count(); i++) + comboItems.append(m_memCombo->text(i)); + + config->setMemoryFormat(comboItems); +} + +void KSim::MemoryPrefs::readConfig(KSim::Config *config) +{ + m_memCheck->setChecked(config->showMemory()); + + QStringList::ConstIterator it; + QStringList items = config->memoryFormatList(); + for (it = items.begin(); it != items.end(); ++it) + if (!m_memCombo->contains(*it)) + m_memCombo->insertItem(*it); + + m_memCombo->setCurrentItem(config->memoryItem()); +} + +void KSim::MemoryPrefs::memoryContextMenu(QPopupMenu *menu) +{ + menu->insertSeparator(); + menu->insertItem(m_addIcon, i18n("Insert Item"), + this, SLOT(insertMemoryItem())); + menu->insertItem(m_removeIcon, i18n("Remove Item"), + this, SLOT(removeMemoryItem())); +} + +void KSim::MemoryPrefs::insertMemoryItem() +{ + QString text = m_memCombo->lineEdit()->text(); + if (!m_memCombo->contains(text)) { + m_memCombo->insertItem(text); + m_memCombo->setCurrentItem(m_memCombo->count() - 1); + } +} + +void KSim::MemoryPrefs::removeMemoryItem() +{ + int currentItem = m_memCombo->currentItem(); + m_memCombo->removeItem(currentItem); + m_memCombo->setCurrentItem(currentItem - 1); +} + +KSim::SwapPrefs::SwapPrefs(QWidget *parent, const char *name) + : QWidget(parent, name) +{ + m_addIcon = SmallIconSet("filenew"); + m_removeIcon = SmallIconSet("editdelete"); + + m_mainLayout = new QVBoxLayout(this); + m_mainLayout->setSpacing(6); + + m_swapCheck = new QCheckBox(this); + m_swapCheck->setText(i18n("Show swap and free swap")); + m_swapCheck->setChecked(true); + m_mainLayout->addWidget(m_swapCheck); + + m_swapCombo = new KComboBox(true, this); + m_swapCombo->setDuplicatesEnabled(false); + m_swapCombo->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, + QSizePolicy::Fixed)); + //m_swapCombo->insertItem(i18n("%tM - %fM free")); + //m_swapCombo->insertItem(i18n("%tM - %uM used")); + + connect(m_swapCombo, + SIGNAL(aboutToShowContextMenu(QPopupMenu *)), + SLOT(swapContextMenu(QPopupMenu *))); + + m_swapAdd = new QPushButton(this); + m_swapAdd->setPixmap(SmallIcon("down")); + connect(m_swapAdd, SIGNAL(clicked()), SLOT(insertSwapItem())); + QToolTip::add(m_swapAdd, i18n("Insert item")); + + m_subLayout = new QHBoxLayout; + m_subLayout->setSpacing(6); + connect(m_swapCheck, SIGNAL(toggled(bool)), + m_swapCombo, SLOT(setEnabled(bool))); + connect(m_swapCheck, SIGNAL(toggled(bool)), + m_swapAdd, SLOT(setEnabled(bool))); + + m_swapFormat = new QLabel(this); + m_swapFormat->setText(i18n("Swap format:")); + m_subLayout->addWidget(m_swapFormat); + + m_subLayout->addWidget(m_swapCombo); + m_subLayout->addWidget(m_swapAdd); + m_mainLayout->addLayout(m_subLayout); + + m_swapInfo = new QLabel(this); + m_swapInfo->setText(i18n("The text in the edit box will be what is " + "displayed as \nthe swap & free swap except the % items " + "will be \nreplaced with the legend")); + m_mainLayout->addWidget(m_swapInfo); + + m_swapBox = new QGroupBox(this); + m_swapBox->setTitle(i18n("Swap Legend")); + m_swapBox->setColumnLayout(0, Qt::Vertical); + m_swapBox->layout()->setSpacing(0); + m_swapBox->layout()->setMargin(0); + m_boxLayout = new QVBoxLayout(m_swapBox->layout()); + m_boxLayout->setAlignment(Qt::AlignTop); + m_boxLayout->setSpacing(6); + m_boxLayout->setMargin(11); + + m_stLabel = new QLabel(m_swapBox); + m_stLabel->setText(i18n("%t - Total swap")); + m_boxLayout->addWidget(m_stLabel); + + m_sfLabel = new QLabel(m_swapBox); + m_sfLabel->setText(i18n("%f - Total free swap")); + m_boxLayout->addWidget(m_sfLabel); + + m_suLabel = new QLabel(m_swapBox); + m_suLabel->setText(i18n("%u - Total used swap")); + m_boxLayout->addWidget(m_suLabel); + m_mainLayout->addWidget(m_swapBox); + + QSpacerItem *spacer = new QSpacerItem(20, 20, + QSizePolicy::Minimum, QSizePolicy::Expanding); + m_mainLayout->addItem(spacer); +} + +KSim::SwapPrefs::~SwapPrefs() +{ +} + +void KSim::SwapPrefs::saveConfig(KSim::Config *config) +{ + config->setSwapItem(m_swapCombo->currentItem()); + + QStringList comboItems; + for (int i = 0; i < m_swapCombo->count(); i++) + comboItems.append(m_swapCombo->text(i)); + + config->setSwapFormat(comboItems); + config->setShowSwap(m_swapCheck->isChecked()); +} + +void KSim::SwapPrefs::readConfig(KSim::Config *config) +{ + m_swapCheck->setChecked(config->showSwap()); + + QStringList::ConstIterator it; + QStringList items = config->swapFormatList(); + for (it = items.begin(); it != items.end(); ++it) + if (!m_swapCombo->contains(*it)) + m_swapCombo->insertItem(*it); + + m_swapCombo->setCurrentItem(config->swapItem()); +} + +void KSim::SwapPrefs::swapContextMenu(QPopupMenu *menu) +{ + menu->insertSeparator(); + menu->insertItem(m_addIcon, i18n("Insert Item"), this, SLOT(insertSwapItem())); + menu->insertItem(m_removeIcon, i18n("Remove Item"), this, SLOT(removeSwapItem())); +} + +void KSim::SwapPrefs::insertSwapItem() +{ + QString text = m_swapCombo->lineEdit()->text(); + if (!m_swapCombo->contains(text)) { + m_swapCombo->insertItem(text); + m_swapCombo->setCurrentItem(m_swapCombo->count() - 1); + } +} + +void KSim::SwapPrefs::removeSwapItem() +{ + int currentItem = m_swapCombo->currentItem(); + m_swapCombo->removeItem(currentItem); + m_swapCombo->setCurrentItem(currentItem - 1); +} diff --git a/ksim/generalprefs.h b/ksim/generalprefs.h new file mode 100644 index 0000000..b163dac --- /dev/null +++ b/ksim/generalprefs.h @@ -0,0 +1,185 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#ifndef GENERAL_H +#define GENERAL_H + +#include <qwidget.h> +#include <qiconset.h> + +class QVBoxLayout; +class QHBoxLayout; +class QGridLayout; +class QCheckBox; +class QGroupBox; +class QLabel; +class QLineEdit; +class QTabWidget; +class KComboBox; +class QPopupMenu; +class QPushButton; +class KIntSpinBox; + +namespace KSim +{ + class Config; + + class GeneralPrefs : public QWidget + { + Q_OBJECT + public: + GeneralPrefs(QWidget *parent, const char *name=0); + ~GeneralPrefs(); + + public slots: + void saveConfig(KSim::Config *); + void readConfig(KSim::Config *); + + private: + QGridLayout *m_mainLayout; + QGroupBox *m_sizeBox; + QLabel *m_sizeHLabel; + KIntSpinBox *m_sizeHSpin; + QLabel *m_sizeWLabel; + KIntSpinBox *m_sizeWSpin; + QCheckBox *m_displayFqdn; + QCheckBox *m_recolourThemes; + }; + + class ClockPrefs : public QWidget + { + Q_OBJECT + public: + ClockPrefs(QWidget *parent, const char *name=0); + ~ClockPrefs(); + + public slots: + void saveConfig(KSim::Config *); + void readConfig(KSim::Config *); + + private: + QVBoxLayout *m_mainLayout; + QCheckBox *m_timeCheck; + QCheckBox *m_dateCheck; + }; + + class UptimePrefs : public QWidget + { + Q_OBJECT + public: + UptimePrefs(QWidget *parent, const char *name=0); + ~UptimePrefs(); + + public slots: + void saveConfig(KSim::Config *); + void readConfig(KSim::Config *); + + private slots: + void uptimeContextMenu(QPopupMenu *); + void insertUptimeItem(); + void removeUptimeItem(); + + private: + QVBoxLayout *m_mainLayout; + QHBoxLayout *m_subLayout; + QVBoxLayout *m_boxLayout; + KComboBox *m_uptimeCombo; + QPushButton *m_uptimeAdd; + QCheckBox *m_uptimeCheck; + QLabel *m_formatLabel; + QLabel *m_uptimeInfo; + QGroupBox *m_uptimeBox; + QLabel *m_udLabel; + QLabel *m_uhLabel; + QLabel *m_umLabel; + QLabel *m_usLabel; + QIconSet m_addIcon; + QIconSet m_removeIcon; + }; + + class MemoryPrefs : public QWidget + { + Q_OBJECT + public: + MemoryPrefs(QWidget *parent, const char *name=0); + ~MemoryPrefs(); + + public slots: + void saveConfig(KSim::Config *); + void readConfig(KSim::Config *); + + private slots: + void memoryContextMenu(QPopupMenu *); + void insertMemoryItem(); + void removeMemoryItem(); + + private: + QVBoxLayout *m_mainLayout; + QHBoxLayout *m_subLayout; + QVBoxLayout *m_boxLayout; + QCheckBox *m_memCheck; + QLabel *m_memFormat; + KComboBox *m_memCombo; + QLabel *m_memInfo; + QGroupBox *m_memBox; + QLabel *m_mtLabel; + QLabel *m_mfLabel; + QLabel *m_muLabel; + QLabel *m_mcLabel; + QLabel *m_mbLabel; + QLabel *m_msLabel; + QPushButton *m_memoryAdd; + QIconSet m_addIcon; + QIconSet m_removeIcon; + }; + + class SwapPrefs : public QWidget + { + Q_OBJECT + public: + SwapPrefs(QWidget *parent, const char *name=0); + ~SwapPrefs(); + + public slots: + void saveConfig(KSim::Config *); + void readConfig(KSim::Config *); + + private slots: + void swapContextMenu(QPopupMenu *); + void insertSwapItem(); + void removeSwapItem(); + + private: + QVBoxLayout *m_mainLayout; + QHBoxLayout *m_subLayout; + QVBoxLayout *m_boxLayout; + QCheckBox *m_swapCheck; + QLabel *m_swapFormat; + KComboBox *m_swapCombo; + QLabel *m_swapInfo; + QGroupBox *m_swapBox; + QLabel *m_stLabel; + QLabel *m_sfLabel; + QLabel *m_suLabel; + QPushButton *m_swapAdd; + QIconSet m_addIcon; + QIconSet m_removeIcon; + }; +} +#endif diff --git a/ksim/ksim.cpp b/ksim/ksim.cpp new file mode 100644 index 0000000..86ea980 --- /dev/null +++ b/ksim/ksim.cpp @@ -0,0 +1,129 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#include "ksim.h" +#include "ksimview.h" +#include <ksimconfig.h> +#include <common.h> + +#include <qlayout.h> + +#include <kaboutapplication.h> +#include <kbugreport.h> +#include <kaboutdata.h> +#include <dcopclient.h> +#include <kmessagebox.h> +#include <kglobal.h> +#include <klocale.h> + +extern "C" +{ + KDE_EXPORT KPanelExtension *init(QWidget *parent, const QString &configFile) + { + KGlobal::locale()->insertCatalogue("ksim"); + return new KSim::PanelExtension(configFile, KPanelExtension::Normal, + KPanelExtension::About | KPanelExtension::Help | + KPanelExtension::Preferences | KPanelExtension::ReportBug, + parent, "ksim"); + } +} + +KSim::PanelExtension::PanelExtension(const QString &configFile, + Type type, int actions, QWidget *parent, const char *name) + : KPanelExtension(configFile, type, actions, parent, name) +{ + m_dcopClient = new DCOPClient; + m_view = new KSim::MainView(config(), true, this, "m_view"); + m_view->positionChange(orientation()); + + m_dcopClient->registerAs(name, false); + + m_aboutData = new KAboutData(name, I18N_NOOP("KSim"), KSIM_VERSION_STRING, + I18N_NOOP("A plugin based system monitor for KDE"), + KAboutData::License_GPL, I18N_NOOP("(C) 2001-2003 Robbie Ward\n(C) 2005 Reuben Sutton")); + m_aboutData->addAuthor("Reuben Sutton", I18N_NOOP("Maintainer"),"reuben.sutton@gmail.com"); + m_aboutData->addAuthor("Robbie Ward", I18N_NOOP("Original Author"), + "linuxphreak@gmx.co.uk"); + m_aboutData->addAuthor("Jason Katz-Brown", I18N_NOOP("Developer"), + "jason@katzbrown.com"); + m_aboutData->addAuthor("Heitham Omar", I18N_NOOP("Some FreeBSD ports"), + "super_ice@ntlworld.com"); + m_aboutData->addAuthor("Otto Bruggeman", I18N_NOOP("Testing, Bug fixing and some help"), + "bruggie@home.nl"); +} + +KSim::PanelExtension::~PanelExtension() +{ + delete m_aboutData; + delete m_dcopClient; +} + +QSize KSim::PanelExtension::sizeHint(Position p, QSize maxSize) const +{ + return m_view->sizeHint(p, maxSize); +} + +void KSim::PanelExtension::resizeEvent(QResizeEvent *) +{ + m_view->resize(size()); +} + +KPanelExtension::Position KSim::PanelExtension::preferedPosition() const +{ + return KPanelExtension::Right; +} + +void KSim::PanelExtension::reparse() +{ + emit updateLayout(); +} + +void KSim::PanelExtension::show() +{ + KPanelExtension::show(); + + reparse(); +} + +void KSim::PanelExtension::about() +{ + KAboutApplication(m_aboutData).exec(); +} + +void KSim::PanelExtension::help() +{ +} + +void KSim::PanelExtension::preferences() +{ + m_view->preferences(); +} + +void KSim::PanelExtension::reportBug() +{ + KBugReport(this, true, m_aboutData).exec(); +} + +void KSim::PanelExtension::positionChange(Position) +{ + m_view->positionChange(orientation()); +} + +#include "ksim.moc" diff --git a/ksim/ksim.desktop b/ksim/ksim.desktop new file mode 100644 index 0000000..8f4934a --- /dev/null +++ b/ksim/ksim.desktop @@ -0,0 +1,134 @@ +[Desktop Entry] +GenericName=System Monitor +GenericName[af]=Stelsel Monitor +GenericName[ar]=مراقب النظام +GenericName[az]=Sistem Ä°zlÉ™yici +GenericName[bg]=Мониторинг на ÑиÑтемата +GenericName[br]=Diskwel saviad ar reizhiad +GenericName[bs]=Monitor sistema +GenericName[ca]=Monitor del sistema +GenericName[cs]=Monitor systému +GenericName[cy]=Monitr Cysawd +GenericName[da]=SystemovervÃ¥gningsprogram +GenericName[de]=Systemüberwachung +GenericName[el]=Επόπτης συστήματος +GenericName[eo]=Sistemstato-programo +GenericName[es]=Monitor del sistema +GenericName[et]=Süsteemi monitor +GenericName[eu]=Sistemaren Begiralea +GenericName[fa]=نمایشگر سیستم +GenericName[fi]=Järjestelmänvalvontaohjelma +GenericName[fr]=Indicateurs du système +GenericName[ga]=Monatóir Córais +GenericName[gl]=Monitor do Sistema +GenericName[he]=צג מערכת +GenericName[hi]=तंतà¥à¤° मॉनीटर +GenericName[hr]=Monitor sustava +GenericName[hu]=Rendszermonitor +GenericName[id]=Monitor Sistem +GenericName[is]=Kerfiseftirlit +GenericName[it]=Controllo di sistema +GenericName[ja]=システムモニタ +GenericName[ka]=სისტემური მáƒáƒœáƒ˜áƒ¢áƒáƒ ი +GenericName[kk]=Жүйені қадағалау +GenericName[km]=កម្មវិធី​ážáŸ’ážšáž½ážáž–áž·áž“áž·ážáŸ’យ​ប្រពáŸáž“្ធ +GenericName[ko]=Xìš© 시스템 지켜보기 (Xosview) +GenericName[lt]=Sistemos stebÄ—tojas +GenericName[lv]=SistÄ“mas Monitors +GenericName[mk]=Монитор на ÑиÑтемот +GenericName[ms]=Pemerhati Sistem +GenericName[mt]=Monitur tas-sistema +GenericName[nb]=SystemovervÃ¥ker +GenericName[nds]=Systeemkieker +GenericName[ne]=पà¥à¤°à¤£à¤¾à¤²à¥€ मोनिटर +GenericName[nl]=Systeemmonitor +GenericName[nn]=Systemovervakar +GenericName[nso]=Molebeledi wa System +GenericName[pa]=ਸਿਸਟਮ ਨਿਗਰਾਨ +GenericName[pl]=Monitor systemu +GenericName[pt]=Monitor do Sistema +GenericName[pt_BR]=Monitor de sistema +GenericName[ro]=Program de monitorizare a sistemului +GenericName[ru]=СиÑтемный монитор +GenericName[rw]=Mugaragaza Sisitemu +GenericName[sk]=Monitor systému +GenericName[sl]=Sistemski nadzornik +GenericName[sr]=Ðадгледање ÑиÑтема +GenericName[sr@Latn]=Nadgledanje sistema +GenericName[sv]=Systemövervakare +GenericName[ta]=அமைபà¯à®ªà¯ கணà¯à®•à®¾à®£à®¿ +GenericName[tg]=Дидабони СиÑтемавӣ +GenericName[th]=สà¸à¸”ส่à¸à¸‡à¸à¸²à¸£à¸—ำงานขà¸à¸‡à¸£à¸°à¸šà¸š +GenericName[tr]=Sistem Ä°zleyici +GenericName[uk]=Монітор ÑиÑтеми +GenericName[uz]=Tizimni nazorat qilish +GenericName[uz@cyrillic]=Тизимни назорат қилиш +GenericName[ven]=Mugadi wa Maitele +GenericName[vi]=Trình theo dõi há»Ethống +GenericName[wa]=Corwaitoe do sistinme +GenericName[xh]=Umphendli Wendlela Esetyenziswayo +GenericName[zh_CN]=系统监视器 +GenericName[zh_TW]=系統監視器 +GenericName[zu]=Umlawuli Wesistimu +Comment=System Information Monitor (GKrellM style) +Comment[ar]=مراقب معلومات نظام K (أسلوب GKrellM) +Comment[bg]=Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° ÑÑŠÑтоÑнието на ÑиÑтемата (Ñтил GKrellM) +Comment[bs]=Nadzor sistemskih informacija (nalik na GKrellM) +Comment[ca]=Monitor d'informació del sistema (similar a GKrellM) +Comment[cs]=Monitor systémových informacà (ve stulu programu GKrellM) +Comment[da]=SysteminformationsovervÃ¥gning (GKrellM-lignende) +Comment[de]=System-Informationsüberwachung (GKrellM-Stil) +Comment[el]=Επόπτης πληÏοφοÏιών συστήματος (στο στυλ του GKrellM) +Comment[eo]=Monitoro por Sisteminformoj (GKrellM-stilo) +Comment[es]=Monitor de información del sistema (estilo GKrellM) +Comment[et]=Süsteemi monitooring (GKrellM stiil) +Comment[eu]=Sistemaren Informazioaren Begiralea (GKrellM estiloa) +Comment[fa]=نمایشگر اطلاعات سیستم (GKrellM سبک) +Comment[fi]=Järjestelmätietomonitori (GKrellM-tyylinen) +Comment[fr]=Indicateur d'informations système (dans le style de GKrellM) +Comment[ga]=Monatóir Eolais an Chórais (stÃl GKrellM) +Comment[he]=צג מידע מערכת (× ×•×¡×— GKrellM) +Comment[hu]=Rendszermonitor (GKrellM-stÃlusú) +Comment[is]=Kerfisupplýsingavaki (lÃkur GKrellM) +Comment[it]=Controllo delle informazioni di sistema (simile a GKrellM) +Comment[ja]=ã‚·ã‚¹ãƒ†ãƒ æƒ…å ±ãƒ¢ãƒ‹ã‚¿ (GKrellM スタイル) +Comment[ka]= სისტემური ინფáƒáƒ მáƒáƒªáƒ˜áƒ˜áƒ¡ მáƒáƒœáƒ˜áƒ¢áƒáƒ ი (GKrellM style) +Comment[kk]=Жүені қадағалау ақпараты (GKrellM Ñтилінде) +Comment[km]=កម្មវិធី​ážáŸ’ážšáž½ážáž–áž·áž“áž·ážáŸ’យ​ពáŸážáŸŒáž˜áž¶áž“​របស់​ប្រពáŸáž“្ធ (GKrellM style) +Comment[lt]=Sistemos informacijos stebÄ—tojas (GKrellM stilius) +Comment[nb]=OvervÃ¥kning av K systeminformasjon (GKrellM stil) +Comment[nds]=Kieker för Systeeminformatschonen (GKrellM-Stil) +Comment[ne]=पà¥à¤°à¤£à¤¾à¤²à¥€ सूचना मोनिटर (GKrellM शैली) +Comment[nl]=Systeeminformatiemonitor (gKrellM-stijl) +Comment[nn]=Systeminfovisar (GKrellM-stil) +Comment[pa]=ਸਿਸਟਮ ਜਾਣਕਾਰੀ ਨਿਗਰਾਨ (GKrellM ਸ਼ੈਲੀ) +Comment[pl]=Informacja o stanie systemu (w stylu GKrellM) +Comment[pt]=Monitor de Informações do Sistema (estilo GKrellM) +Comment[pt_BR]=Monitor de Informações do Sistema (estilo GKrellM) +Comment[ru]=Информационный монитор (в Ñтиле GKrellM) +Comment[sk]=Monitor systémových informácià (v Å¡týle GKrellM) +Comment[sl]=Nadzornik sistemskih informacij (v slogu GKrellM) +Comment[sr]=Ðадгледање ÑиÑтемÑких информација (у Ñтилу GKrellM-а) +Comment[sr@Latn]=Nadgledanje sistemskih informacija (u stilu GKrellM-a) +Comment[sv]=Systeminformationsövervakare (Gkrellm-stil) +Comment[tr]=Sistem Bildirimileri Ä°zleyici (GKrellM stili) +Comment[uk]=Монітор ÑиÑтемної інформації (в Ñтилі GKrellM) +Comment[zh_CN]=系统信æ¯ç›‘视器(GKrellM é£Žæ ¼) +Comment[zh_TW]=系統資訊監視器 (GKrellM é¢¨æ ¼) +DocPath=ksim/index.html +Icon=ksim +MimeType= +Name=KSim +Name[af]=Ksim +Name[cy]=kSim +Name[eo]=Simulilo +Name[hi]=के-सिम +Name[ne]=केडीई सिम +Name[sv]=Ksim +Name[ta]=கேசிம௠+Name[th]=สà¸à¸”ส่à¸à¸‡à¸£à¸°à¸šà¸š +Name[zh_TW]=KSim 系統監視器 +X-KDE-Library=ksim_panelextension +X-KDE-UniqueApplet=true +Categories=Qt;KDE;System; +Hidden=false diff --git a/ksim/ksim.h b/ksim/ksim.h new file mode 100644 index 0000000..8a43a06 --- /dev/null +++ b/ksim/ksim.h @@ -0,0 +1,67 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#ifndef KSIMEXTENSION_H +#define KSIMEXTENSION_H + +#include <kpanelextension.h> + +class QBoxLayout; +class KAboutData; +class KInstance; +class DCOPClient; + +namespace KSim +{ + class MainView; + + class PanelExtension : public KPanelExtension + { + Q_OBJECT + public: + PanelExtension( const QString & configFile, Type type, + int actions, QWidget * parent, const char * name); + + ~PanelExtension(); + + QSize sizeHint( Position, QSize maxSize ) const; + void resizeEvent(QResizeEvent *); + Position preferedPosition() const; + + void reparse(); + + public slots: + void show(); + + protected: + void about(); + void help(); + void preferences(); + void reportBug(); + void positionChange( Position ); + + private: + KSim::MainView * m_view; + QBoxLayout * m_layout; + KAboutData * m_aboutData; + DCOPClient * m_dcopClient; + }; +} +#endif diff --git a/ksim/ksim_panelextensionrc b/ksim/ksim_panelextensionrc new file mode 100644 index 0000000..8986d4d --- /dev/null +++ b/ksim/ksim_panelextensionrc @@ -0,0 +1,81 @@ +[CpuPlugin] +Cpus=cpu 0 +DisplayNice=true +Cpu0_options=%T + +[DiskPlugin] +UseSeperatly=true +Disks=complete + +[Fsystem] +ShowPercentage=true +mountEntries=/ +scrollerUpdate=65 +stackItems=true +updateValue=60 + +[General] +Alignment=0 +AutoHideDelay=3 +AutoHidePanel=false +AutoHideSwitch=true +BackgroundHide=false +CustomSize=58 +ExpandSize=true +HideAnimation=true +HideAnimationSpeed=40 +HideButtonSize=14 +Position=1 +ResizeableHandle=false +ShowLeftHideButton=true +ShowRightHideButton=false +Size=2 +SizePercentage=1 +UnhideLocation=6 +XineramaScreen=0 + +[General Options] +Width=-1 + +[Misc] +MemoryFormat=Memory: %fM/%tM +MemoryItem=0 +ShowMemory=true +ShowSwap=true +ShowUptime=true +SwapFormat=Swap: %fM/%tM +SwapItem=0 +UptimeFormat=%hh:%mm:%ss,%dd %h:%m,Uptime: %h:%m:%s +UptimeItem=0 +GraphSize=58,40 +savePos=false +showDock=true +showDate=false +showTime=false + +[Monitors] +cpu=true +filesystem=true +disk=true +net=true + +[Net] +deviceAmount=1 + +[Sensors] +sensorLocations=/usr/lib/,/usr/local/lib/ + +[Theme] +Alternative=0 +FontItem=4 +Name=ksim + +[device-0] +cCommand= +commands=false +dCommand= +deviceFormat=%h:%m:%s +deviceName=eth0 +showGraph=true +showLabel=true +showTimer=false diff --git a/ksim/ksimframe.cpp b/ksim/ksimframe.cpp new file mode 100644 index 0000000..e69a6c6 --- /dev/null +++ b/ksim/ksimframe.cpp @@ -0,0 +1,94 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#include "ksimframe.h" +#include "ksimframe.moc" +#include <themeloader.h> +#include "ksim.h" +#include "themetypes.h" + +KSim::Frame::Frame(int type, QWidget *parent, const char *name) + : QWidget (parent, name) +{ + setType(type); + + setBackgroundMode(NoBackground); + configureObject(); +} + +KSim::Frame::~Frame() +{ +} + +void KSim::Frame::configureObject(bool repaintWidget) +{ + m_image.load(themeLoader().current().framePixmap(type())); + + switch (type()) { + case KSim::Types::TopFrame: + setFrameHeight(themeLoader().current().frameTopHeight()); + break; + case KSim::Types::BottomFrame: + setFrameHeight(themeLoader().current().frameBottomHeight()); + break; + case KSim::Types::LeftFrame: + setFrameWidth(themeLoader().current().frameLeftWidth()); + break; + case KSim::Types::RightFrame: + setFrameWidth(themeLoader().current().frameRightWidth()); + break; + } + + themeLoader().reColourImage(m_image); + m_background.convertFromImage(m_image.smoothScale(size())); + + if (repaintWidget) + update(); +} + +void KSim::Frame::paintEvent(QPaintEvent *) +{ + bitBlt(this, 0, 0, &m_background); +} + +void KSim::Frame::resizeEvent(QResizeEvent *ev) +{ + m_background.convertFromImage(m_image.smoothScale(ev->size())); + QWidget::resizeEvent(ev); +} + +void KSim::Frame::setFrameHeight(int height) +{ + if (!height) { + setFixedHeight(m_image.height()); + return; + } + + setFixedHeight(height); +} + +void KSim::Frame::setFrameWidth(int width) +{ + if (!width) { + setFixedWidth(m_image.width()); + return; + } + + setFixedWidth(width); +} diff --git a/ksim/ksimframe.h b/ksim/ksimframe.h new file mode 100644 index 0000000..b7b397f --- /dev/null +++ b/ksim/ksimframe.h @@ -0,0 +1,63 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#ifndef KSIMFRAME_H +#define KSIMFRAME_H + +#include <qwidget.h> +#include <qimage.h> +#include <common.h> + +namespace KSim +{ + class PanelExtension; + + /** + * @internal + */ + class Frame : public QWidget, public KSim::Base + { + Q_OBJECT + public: + Frame(int type, QWidget *parent, const char *name = 0); + ~Frame(); + + const QPixmap *const background() const { return &m_background; } + virtual void configureObject(bool repaintWidget=true); + + protected: + virtual void paintEvent(QPaintEvent *); + virtual void resizeEvent(QResizeEvent *); + + private: + // helper functions to make + // the source more readable + void setFrameHeight(int height); + void setFrameWidth(int width); + + int m_origWidth; + int m_origHeight; + QPoint m_globalBottomRight; + QPoint m_globalTopLeft; + QPoint m_origPos; + QImage m_image; + QPixmap m_background; + }; +} +#endif diff --git a/ksim/ksimpref.cpp b/ksim/ksimpref.cpp new file mode 100644 index 0000000..d8aa12d --- /dev/null +++ b/ksim/ksimpref.cpp @@ -0,0 +1,260 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#include "ksimpref.h" +#include "ksimpref.moc" + +#include "generalprefs.h" +#include "monitorprefs.h" +#include "themeprefs.h" +#include <pluginloader.h> +#include <ksimconfig.h> +#include <pluginmodule.h> + +#include <klocale.h> +#include <kiconloader.h> +#include <kdebug.h> +#include <kstandarddirs.h> +#include <kmessagebox.h> + +#include <qhbox.h> +#include <qframe.h> + +KSim::ConfigDialog::ConfigDialog(KSim::Config *config, + QWidget *parent, const char *name) + : KDialogBase(TreeList, i18n("Configure"), + Help | Ok | Apply | Close, Ok, parent, name, true, true) +{ + resize(466, 363); + setShowIconsInTreeList(true); + setRootIsDecorated(false); + + m_config = config; + + setFolderIcon(QStringList(' ' + i18n("Plugins")), + BarIcon("folder", KIcon::SizeSmall)); + setFolderIcon(QStringList(' ' + i18n("Miscellaneous")), + BarIcon("misc", KIcon::SizeSmall)); + + QFrame *monitors = addHBoxPage(' ' + i18n("Monitors"), + i18n("Monitors Installed"), BarIcon("ksim", KIcon::SizeSmall)); + m_monPage = new KSim::MonitorPrefs(monitors); + + QStringList list; + list << ' ' + i18n("Miscellaneous") << ' ' + i18n("General"); + QFrame *general = addHBoxPage(list, i18n("General Options"), + SmallIcon("misc")); + m_generalPage = new KSim::GeneralPrefs(general); + list.clear(); + + list << ' ' + i18n("Miscellaneous") << ' ' + i18n("Clock"); + QFrame *clock = addHBoxPage(list, i18n("Clock Options"), + QPixmap(locate("data", "ksim/pics/clock.png"))); + m_clockPage = new KSim::ClockPrefs(clock); + list.clear(); + + list << ' ' + i18n("Miscellaneous") << ' ' + i18n("Uptime"); + QFrame *uptime = addHBoxPage(list, i18n("Uptime Options"), + QPixmap(locate("data", "ksim/pics/uptime.png"))); + m_uptimePage = new KSim::UptimePrefs(uptime); + list.clear(); + + list << ' ' + i18n("Miscellaneous") << ' ' + i18n("Memory"); + QFrame *memory = addHBoxPage(list, i18n("Memory Options"), + SmallIcon("memory")); + m_memoryPage = new KSim::MemoryPrefs(memory); + list.clear(); + + list << ' ' + i18n("Miscellaneous") << ' ' + i18n("Swap"); + QFrame *swap = addHBoxPage(list, i18n("Swap Options"), + SmallIcon("hdd_unmount")); + m_swapPage = new KSim::SwapPrefs(swap); + + QFrame *theme = addHBoxPage(' ' + i18n("Themes"), + i18n("Theme Selector"), BarIcon("folder_image", KIcon::SizeSmall)); + m_themePage = new KSim::ThemePrefs(theme); + + connect(this, SIGNAL(applyClicked()), SLOT(savePrefs())); + connect(this, SIGNAL(okClicked()), SLOT(closePrefs())); + connect(this, SIGNAL(closeClicked()), SLOT(loadPluginConfig())); + connect(parent, SIGNAL(reload()), SLOT(reload())); + + KSim::PluginList::ConstIterator it; + const KSim::PluginList &pluginList = KSim::PluginLoader::self().pluginList(); + for (it = pluginList.begin(); it != pluginList.end(); ++it) + createPage((*it)); + + readConfig(); +} + +KSim::ConfigDialog::~ConfigDialog() +{ + ChangedPluginList::ConstIterator it; + for (it = m_currentPlugins.begin(); it != m_currentPlugins.end(); ++it) { + if ((*it).isEnabled()) + removePage((*it).libName()); + } +} + +void KSim::ConfigDialog::reload() +{ + enableButtons(); +} + +void KSim::ConfigDialog::removePage(const QCString &name) +{ + const KSim::Plugin &plugin = KSim::PluginLoader::self().find(name); + if (plugin.isNull() || !plugin.configPage()) { + KMessageBox::sorry(0, i18n("Failed to remove %1's config page due to the " + "plugin not being loaded or the config page has not been created").arg(name)); + return; + } + + QWidget *frame = plugin.configPage()->parentWidget(); + // reparent the widget if the parent is not null + if (frame) { + plugin.configPage()->hide(); + plugin.configPage()->reparent(0, QPoint(0, 0), false); + // delete the frame so it removes the page from the config dialog + delete frame; + kdDebug(2003) << "removing " << name << " from KSimPref" << endl; + } +} + +void KSim::ConfigDialog::createPage(const QCString &name) +{ + const KSim::Plugin &plugin = KSim::PluginLoader::self().find(name); + createPage(plugin); +} + +void KSim::ConfigDialog::createPage(const KSim::Plugin &plugin) +{ + if (plugin.isNull() || !plugin.configPage()) { + KMessageBox::sorry(0, i18n("Failed to add %1's config page due to the plugin" + " not being loaded or the config page has not been created") + .arg(plugin.libName())); + return; + } + + kdDebug(2003) << "adding " << plugin.libName() << " to KSimPref" << endl; + + QStringList list; + list << ' ' + i18n("Plugins") << ' ' + plugin.name(); + QFrame *pluginFrame = addHBoxPage(list, i18n("%1 Options").arg(plugin.name()), + plugin.icon()); + + plugin.configPage()->reparent(pluginFrame, QPoint(0, 0), true); + plugin.configPage()->readConfig(); + +// TODO: implement this correctly one day +// connect (info.configPage(), SIGNAL(pageChanged()), +// this, SLOT(enableButtons())); +} + +void KSim::ConfigDialog::savePrefs() +{ + saveConfig(true); +} + +void KSim::ConfigDialog::saveConfig(bool reload) +{ + disableButtons(); + + m_monPage->saveConfig(m_config); + m_generalPage->saveConfig(m_config); + m_clockPage->saveConfig(m_config); + m_uptimePage->saveConfig(m_config); + m_memoryPage->saveConfig(m_config); + m_swapPage->saveConfig(m_config); + m_themePage->saveConfig(m_config); + + ChangedPluginList changedPlugins; + for (QListViewItemIterator it(m_monPage); it.current(); ++it) { + QCheckListItem *item = static_cast<QCheckListItem *>(it.current()); + KSim::PluginInfo info = KSim::PluginLoader::self().findPluginInfo(item->text(0), + KSim::PluginLoader::Name); + changedPlugins.append(ChangedPlugin(item->isOn(), + info.libName(true), item->text(0), info.location(), + findPlugin(item->text(0)).isEnabled())); + + KSim::PluginLoader::self().find(info).setEnabled(item->isOn()); + } + + m_currentPlugins = changedPlugins; + emit reparse(reload, changedPlugins); +} + +void KSim::ConfigDialog::readConfig() +{ + m_monPage->readConfig(m_config); + m_generalPage->readConfig(m_config); + m_clockPage->readConfig(m_config); + m_uptimePage->readConfig(m_config); + m_memoryPage->readConfig(m_config); + m_swapPage->readConfig(m_config); + m_themePage->readConfig(m_config); + + m_currentPlugins.clear(); + for (QListViewItemIterator it(m_monPage); it.current(); ++it) { + QCheckListItem *item = static_cast<QCheckListItem *>(it.current()); + KSim::PluginInfo info = KSim::PluginLoader::self().findPluginInfo(item->text(0), + KSim::PluginLoader::Name); + m_currentPlugins.append(ChangedPlugin(item->isOn(), + info.libName(true), item->text(0), info.location())); + } +} + +void KSim::ConfigDialog::closePrefs() +{ + saveConfig(false); + close(); +} + +void KSim::ConfigDialog::loadPluginConfig() +{ + const KSim::PluginList &list = KSim::PluginLoader::self().pluginList(); + KSim::PluginList::ConstIterator it; + for (it = list.begin(); it != list.end(); ++it) { + if ((*it).configPage()) + (*it).configPage()->readConfig(); + } +} + +void KSim::ConfigDialog::enableButtons() +{ + enableButtonApply(true); + enableButtonOK(true); +} + +void KSim::ConfigDialog::disableButtons() +{ + enableButtonApply(false); + enableButtonOK(false); +} + +const KSim::ChangedPlugin &KSim::ConfigDialog::findPlugin(const QString &name) const +{ + ChangedPluginList::ConstIterator it; + for (it = m_currentPlugins.begin(); it != m_currentPlugins.end(); ++it) { + if ((*it).name() == name) + return (*it); + } + + return *m_currentPlugins.end(); +} diff --git a/ksim/ksimpref.h b/ksim/ksimpref.h new file mode 100644 index 0000000..8e560a8 --- /dev/null +++ b/ksim/ksimpref.h @@ -0,0 +1,112 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#ifndef KSIMPREF_H +#define KSIMPREF_H + +#include <kdialogbase.h> +#include <kdelibs_export.h> + +class QFrame; +class KDesktopFile; +namespace KSim +{ + class Config; + class Plugin; + class MonitorPrefs; + class GeneralPrefs; + class ClockPrefs; + class UptimePrefs; + class MemoryPrefs; + class SwapPrefs; + class ThemePrefs; + + class ChangedPlugin + { + public: + ChangedPlugin() : m_name(0) {} + ChangedPlugin(bool enabled, const QCString &libname, + const QString &name, const QString &file) : m_enabled(enabled), + m_libname(libname), m_name(name), m_file(file) {} + ChangedPlugin(bool enabled, const QCString &libname, + const QString &name, const QString &file, bool oldState) + : m_enabled(enabled), m_libname(libname), m_name(name), + m_file(file), m_oldState(oldState) {} + + bool isEnabled() const { return m_enabled; } + bool isDifferent() const { return m_enabled != m_oldState; } + const QCString &libName() const { return m_libname; } + const QString &name() const { return m_name; } + const QString &filename() const { return m_file; } + + private: + bool m_enabled; + QCString m_libname; + QString m_name; + QString m_file; + bool m_oldState; + }; + + class ChangedPluginList : public QValueList<ChangedPlugin> + { + public: + ChangedPluginList() {} + ~ChangedPluginList() {} + }; + + class KDE_EXPORT ConfigDialog : public KDialogBase + { + Q_OBJECT + public: + ConfigDialog(KSim::Config *config, QWidget *parent, const char *name = 0); + ~ConfigDialog(); + + public slots: + void removePage(const QCString &name); + void createPage(const QCString &name); // overload + void createPage(const KSim::Plugin &plugin); + + signals: + void reparse(bool, const KSim::ChangedPluginList &); + + private slots: + void reload(); + void savePrefs(); + void saveConfig(bool); + void readConfig(); + void closePrefs(); + void loadPluginConfig(); + void enableButtons(); + void disableButtons(); + + private: + const KSim::ChangedPlugin &findPlugin(const QString &name) const; + + ChangedPluginList m_currentPlugins; + KSim::MonitorPrefs *m_monPage; + KSim::GeneralPrefs *m_generalPage; + KSim::ClockPrefs *m_clockPage; + KSim::UptimePrefs *m_uptimePage; + KSim::MemoryPrefs *m_memoryPage; + KSim::SwapPrefs *m_swapPage; + KSim::ThemePrefs *m_themePage; + KSim::Config *m_config; + }; +} +#endif diff --git a/ksim/ksimsysinfo.cpp b/ksim/ksimsysinfo.cpp new file mode 100644 index 0000000..724adb6 --- /dev/null +++ b/ksim/ksimsysinfo.cpp @@ -0,0 +1,325 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#include <qtooltip.h> +#include <qlayout.h> +#include <qtimer.h> +#include <qregexp.h> +#include <qtextstream.h> +#include <qdatetime.h> + +#include <kdebug.h> +#include <klocale.h> +#include <kapplication.h> +#include <kglobal.h> + +#include "ksimsysinfo.h" +#include "ksimsysinfo.moc" +#include "systeminfo.h" +#include <label.h> +#include <ksimconfig.h> +#include <progress.h> +#include <themetypes.h> + +#include <time.h> +#include <string.h> + +KSim::Sysinfo::Sysinfo(KSim::Config *config, + QWidget *parent, const char *name, WFlags fl) + : DCOPObject("sysinfo"), QWidget(parent, name, fl) +{ + m_config = config; + m_layout = new QVBoxLayout(this); + + m_timeLabel = 0L; + m_dateLabel = 0L; + m_uptimeLabel = 0L; + m_memLabel = 0L; + m_swapLabel = 0L; + //m_procsLabel = 0L; + + m_timer = new QTimer(this); + connect(m_timer, SIGNAL(timeout()), SLOT(clockUptimeUpdate())); + + m_sysTimer = new QTimer(this); + connect(m_sysTimer, SIGNAL(timeout()), SLOT(sysUpdate())); + + createView(); +} + +KSim::Sysinfo::~Sysinfo() +{ + // remember to cleanup + System::cleanup(); +} + +void KSim::Sysinfo::clockUptimeUpdate() +{ + QString time; + static bool updateDate = true; + + if (m_timeLabel) { + QTime now = QTime::currentTime(); + time = KGlobal::locale()->formatTime(now, true); + if ( now == QTime(0, 0) ) + updateDate = true; + + m_timeLabel->setText(time); + } + + // only update the date when necessary + if (m_dateLabel) { + if (updateDate) { + m_dateLabel->setText(KGlobal::locale()->formatDate(QDate::currentDate())); + updateDate = false; + } + } + else { + updateDate = true; + } + + if (m_uptimeLabel) { + QString uptime = m_config->uptimeFormat(); + ++m_totalUptime; + long uptimeDays, uptimeHours, uptimeMins, uptimeSecs; + + uptimeHours = m_totalUptime / 3600; + uptimeDays = uptimeHours / 24; + uptimeMins = (m_totalUptime - uptimeHours * 3600) / 60; + uptimeSecs = m_totalUptime % 60; + + QString days; + QString hours; + QString minutes; + QString seconds; + + // found days so we have to modify hours + if (uptime.find(QRegExp("%d" ), 0) >= 0) + uptimeHours -= (uptimeDays * 24); + + days.sprintf("%02li", uptimeDays); + hours.sprintf("%02li", uptimeHours); + minutes.sprintf("%02li", uptimeMins); + seconds.sprintf("%02li", uptimeSecs); + + uptime.replace(QRegExp("%d"), days); + uptime.replace(QRegExp("%h"), hours); + uptime.replace(QRegExp("%m"), minutes); + uptime.replace(QRegExp("%s"), seconds); + m_uptimeLabel->setText(uptime); + } +} + +void KSim::Sysinfo::sysUpdate() +{ + const System &system = System::self(); + m_totalUptime = system.uptime(); + + if (m_memLabel) { + QString memory = m_config->memoryFormat(); + unsigned long total = system.totalRam(); + unsigned long free = system.freeRam(); + unsigned long shared = system.sharedRam(); + unsigned long buffer = system.bufferRam(); + unsigned long cache = system.cacheRam(); + unsigned long used = system.usedRam(); + unsigned long allFree = free + buffer + cache; + bool all = memory.find( "%F" ) != -1; + + memory.replace(QRegExp("%s"), QString::number(System::bytesToMegs(shared))); + memory.replace(QRegExp("%b"), QString::number(System::bytesToMegs(buffer))); + memory.replace(QRegExp("%c"), QString::number(System::bytesToMegs(cache))); + memory.replace(QRegExp("%u"), QString::number(System::bytesToMegs(used))); + memory.replace(QRegExp("%t"), QString::number(System::bytesToMegs(total))); + memory.replace(QRegExp("%f"), QString::number(System::bytesToMegs(free))); + memory.replace(QRegExp("%F"), QString::number(System::bytesToMegs(allFree))); + kdDebug(2003) << memory << endl; + m_memLabel->setText("Memory"); + QToolTip::add(m_memLabel, memory ); + + if ( !all ) + m_memLabel->setValue( System::bytesToMegs( total ) - System::bytesToMegs( free ) ); + else + m_memLabel->setValue( System::bytesToMegs( total ) - System::bytesToMegs( allFree ) ); + } + + if (m_swapLabel) { + QString swap = m_config->swapFormat(); + unsigned long total = system.totalSwap(); + unsigned long free = system.freeSwap(); + unsigned long swapUsed = system.usedSwap(); + swap.replace(QRegExp("%u"), QString::number(System::bytesToMegs(swapUsed))); + swap.replace(QRegExp("%t"), QString::number(System::bytesToMegs(total))); + swap.replace(QRegExp("%f"), QString::number(System::bytesToMegs(free))); + m_swapLabel->setText("Swap"); + QToolTip::add(m_swapLabel, swap); + m_swapLabel->setValue(System::bytesToMegs(total) - System::bytesToMegs(free)); + } + +// if (m_config->showProcs()) { +// m_procsLabel->setText(i18n("Procs: %1").arg(sysInfo.procs)); +// } +} + +void KSim::Sysinfo::createView() +{ + stopTimers(); + const System &system = System::self(); + int timeLocation = 0; + int dateLocation = 1; + int uptimeLocation = 2; + int memLocation = 3; + int swapLocation = 4; + // int procsLocation = 5; + int offset = 0; + + if (m_config->showTime()) { + if (!m_timeLabel) { + m_timeLabel = new KSim::Label(this); + m_layout->insertWidget(timeLocation - offset, m_timeLabel); + } + QToolTip::add(m_timeLabel, i18n("Current system time")); + m_timeLabel->show(); + } + else { + offset++; + delete m_timeLabel; + m_timeLabel = 0L; + } + + if (m_config->showDate()) { + if (!m_dateLabel) { + m_dateLabel = new KSim::Label(this); + m_layout->insertWidget(dateLocation - offset, m_dateLabel); + } + QToolTip::add(m_dateLabel, i18n("Current system date")); + m_dateLabel->show(); + } + else { + offset++; + delete m_dateLabel; + m_dateLabel = 0L; + } + + kdDebug(2003) << m_dateLabel << endl; + + if (m_config->showUptime()) { + if (!m_uptimeLabel) { + m_uptimeLabel = new KSim::Label(KSim::Types::Uptime, this); + m_layout->insertWidget(uptimeLocation - offset, m_uptimeLabel); + } + QToolTip::add(m_uptimeLabel, i18n("System uptime")); + m_uptimeLabel->show(); + } + else { + offset++; + delete m_uptimeLabel; + m_uptimeLabel = 0L; + } + + if (m_config->showMemory()) { + if (!m_memLabel) { + m_memLabel = new KSim::Progress(System::bytesToMegs(system.totalRam()), + KSim::Types::Mem, this); + m_layout->insertWidget(memLocation - offset, m_memLabel); + } + + m_memLabel->show(); + } + else { + offset++; + delete m_memLabel; + m_memLabel = 0L; + } + + if (m_config->showSwap()) { + if (!m_swapLabel) { + m_swapLabel = new KSim::Progress(System::bytesToMegs(system.totalSwap()), + KSim::Types::Swap, this); + m_layout->insertWidget(swapLocation - offset, m_swapLabel); + } + m_swapLabel->show(); + } + else { + offset++; + delete m_swapLabel; + m_swapLabel = 0L; + } + + /*if (m_config->showProcs()) { + if (!m_procsLabel) { + m_procsLabel = new KSimLabel(this); + m_layout->insertWidget(procsLocation, m_procsLabel); + } + m_procsLabel->show(); + } + else { + delete m_procsLabel; + m_procsLabel = 0L; + }*/ + +// m_layout->invalidate(); + updateGeometry(); + adjustSize(); + + startTimers(); + sysUpdate(); + clockUptimeUpdate(); +} + +void KSim::Sysinfo::stopTimers() +{ + m_timer->stop(); + m_sysTimer->stop(); +} + +void KSim::Sysinfo::startTimers() +{ + // Cellecting meminfo on fbsd seems to be expensive :( + // so better update the memory display every 5 seconds rather than 1 + // until i can find a better solution (if there is one) + if (!m_sysTimer->isActive() && !m_timer->isActive()) { + m_sysTimer->start(5000); + m_timer->start(1000); + } +} + +QString KSim::Sysinfo::uptime() const +{ + if (m_uptimeLabel) + return m_uptimeLabel->text(); + + return i18n("Uptime display disabled"); +} + +QString KSim::Sysinfo::memInfo() const +{ + if (m_memLabel) + return m_memLabel->text(); + + return i18n("Memory display disabled"); +} + +QString KSim::Sysinfo::swapInfo() const +{ + if (m_swapLabel) + return m_swapLabel->text(); + + return i18n("Swap display disabled"); +} diff --git a/ksim/ksimsysinfo.h b/ksim/ksimsysinfo.h new file mode 100644 index 0000000..5c80d37 --- /dev/null +++ b/ksim/ksimsysinfo.h @@ -0,0 +1,70 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#ifndef SYSINFO_H +#define SYSINFO_H + +#include <qwidget.h> +#include <dcopobject.h> + +class QTimer; +class QVBoxLayout; +namespace KSim +{ + class Config; + class Label; + class Progress; + + class Sysinfo : public QWidget, virtual public DCOPObject + { + Q_OBJECT + K_DCOP + public: + Sysinfo(KSim::Config *config, QWidget *parent=0, + const char *name=0, WFlags fl=0); + ~Sysinfo(); + + k_dcop: + QString uptime() const; + QString memInfo() const; + QString swapInfo() const; + + public slots: + void clockUptimeUpdate(); + void sysUpdate(); + void createView(); + void stopTimers(); + void startTimers(); + + + private: + KSim::Label *m_timeLabel; + KSim::Label *m_dateLabel; + KSim::Label *m_uptimeLabel; + KSim::Progress *m_memLabel; + KSim::Progress *m_swapLabel; + //KSimLabel *m_procsLabel; + QVBoxLayout *m_layout; + QTimer *m_timer; + QTimer *m_sysTimer; + KSim::Config *m_config; + long m_totalUptime; + }; +} +#endif diff --git a/ksim/ksimview.cpp b/ksim/ksimview.cpp new file mode 100644 index 0000000..6f71b66 --- /dev/null +++ b/ksim/ksimview.cpp @@ -0,0 +1,467 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#include "ksimview.h" +#include "ksimview.moc" + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "ksimsysinfo.h" +#include "ksim.h" +#include "ksimframe.h" +#include <label.h> +#include <common.h> +#include <themeloader.h> +#include <pluginmodule.h> +#include <pluginloader.h> +#include <ksimconfig.h> +#include "ksimpref.h" +#include "baselist.h" +#include <themetypes.h> + +#include <kapplication.h> +#include <klocale.h> +#include <kdebug.h> +#include <kstandarddirs.h> +#include <kmessagebox.h> +#include <kdesktopfile.h> +#include <kwin.h> +#include <krun.h> + +#include <qfile.h> +#include <qbitmap.h> +#include <qtimer.h> +#include <qlayout.h> +#include <qobjectlist.h> +#include <qpainter.h> +#include <qcursor.h> +#include <qpopupmenu.h> +#include <qvbox.h> + +#include <unistd.h> +#include <sys/param.h> + +#ifndef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN 64 +#endif + +KSim::MainView::MainView(KConfig *config, + bool loadPlugins, KSim::PanelExtension *topLevel, + const char *name) : DCOPObject("KSim"), + QWidget(topLevel, name) +{ + // create the local "themes" and "monitors" dirs + makeDirs(); + + setBackgroundMode(PaletteBackground); + + m_topLevel = topLevel; + m_oldLocation = 1; + m_prefDialog = 0L; + + m_config = new KSim::Config(config); + + // Make sure the current theme is valid + // if not then revert to the default theme + KSim::ThemeLoader::self().validate(); + + // parse the current theme in case it doesn't have the correct dir structure + if (KSim::ThemeLoader::currentName() != "ksim") + KSim::ThemeLoader::self().parseDir(KSim::ThemeLoader::currentUrl(), + KSim::ThemeLoader::currentAlternative()); + + kdDebug(2003) << "loadPlugins: " << loadPlugins << endl; + + m_subLayout = new QVBoxLayout(this); + + m_topFrame = new KSim::Frame(KSim::Types::TopFrame, this); + m_subLayout->addWidget(m_topFrame); + + m_sizeLayout = new QHBoxLayout; + m_subLayout->addLayout(m_sizeLayout); + + m_leftFrame = new KSim::Frame(KSim::Types::LeftFrame, this); + m_sizeLayout->addWidget(m_leftFrame); + + m_pluginLayout = new QBoxLayout(QBoxLayout::TopToBottom); + m_sizeLayout->addLayout(m_pluginLayout); + + QVBoxLayout *vb = new QVBoxLayout; + QSpacerItem *item = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Expanding); + vb->addItem(item); + + m_hostLabel = new KSim::Label(KSim::Types::Host, this); + m_hostLabel->installEventFilter(this); + vb->addWidget(m_hostLabel); + + m_pluginLayout->addLayout(vb); + + char hostName[MAXHOSTNAMELEN]; + if (gethostname(hostName, sizeof(hostName))) + m_hostLabel->setText(i18n("Unknown")); + else { + QCString host(hostName); + int dotLocation = host.find("."); + if (!m_config->displayFqdn() && dotLocation != -1) + host.truncate(dotLocation); + + m_hostLabel->setText(host); + } + + vb = new QVBoxLayout; + item = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Expanding); + vb->addItem(item); + m_sysinfo = new KSim::Sysinfo(m_config, this); + vb->addWidget(m_sysinfo); + m_pluginLayout->addLayout(vb); + + m_bottomFrame = new KSim::Frame(KSim::Types::BottomFrame, this); + m_subLayout->addWidget(m_bottomFrame); + + m_rightFrame = new KSim::Frame(KSim::Types::RightFrame, this); + m_sizeLayout->addWidget(m_rightFrame); + + connect(&KSim::PluginLoader::self(), + SIGNAL(pluginLoaded(const KSim::Plugin &)), + this, SLOT(addMonitor(const KSim::Plugin &))); + + KSim::ThemeLoader::self().themeColours(this); + + // load the plugins and create the plugin menu + if (loadPlugins) { + addPlugins(); + } + + connect(&m_maskTimer, SIGNAL(timeout()), SLOT(slotMaskMainView())); +} + +KSim::MainView::~MainView() +{ + delete m_config; +} + +void KSim::MainView::show() +{ + maskMainView(); + QWidget::show(); +} + +void KSim::MainView::cleanup() +{ + // delete our configuration dialog and remove + // the plugin config pages from the configuration + // dialog before we unload our plugins + delete m_prefDialog; + + // Clean up the singleton instances + KSim::PluginLoader::cleanup(); +} + +KSim::Config *KSim::MainView::config() const +{ + return m_config; +} + +void KSim::MainView::makeDirs() +{ + QString homeDir = locateLocal("data", "ksim"); + QString themeDir = homeDir + QString::fromLatin1("/themes"); + QString monitorDir = homeDir + QString::fromLatin1("/monitors"); + + // return true if the dirs already exist + if (QFile::exists(themeDir) && QFile::exists(monitorDir)) + return; + + bool themeCreated = KStandardDirs::makeDir(themeDir); + bool monitorCreated = KStandardDirs::makeDir(monitorDir); + + if (!themeCreated || !monitorCreated) + { + KMessageBox::sorry(0, i18n("There was an error while trying to create " + "the local folders. This could be caused by permission problems.")); + } +} + +const QString &KSim::MainView::hostname() const +{ + return m_hostLabel->text(); +} + +void KSim::MainView::slotMaskMainView() +{ + maskMainView(); +} + +void KSim::MainView::maskMainView() +{ + if (!m_topFrame->background()->mask() || + !m_leftFrame->background()->mask() || + !m_rightFrame->background()->mask() || + !m_bottomFrame->background()->mask()) + { + topLevelWidget()->clearMask(); + return; + } + + QBitmap topPixmap(*m_topFrame->background()->mask()); + QBitmap leftPixmap(*m_leftFrame->background()->mask()); + QBitmap rightPixmap(*m_rightFrame->background()->mask()); + QBitmap bottomPixmap(*m_bottomFrame->background()->mask()); + + QSize insideSize(m_pluginLayout->geometry().size()); + + // make a cleared bigrect where we can put our pixmap masks on + QBitmap bigBitmap(topLevelWidget()->size(), true); + + // better return if our bitmap is null so we can avoid crashes + if (bigBitmap.isNull()) + return; + + QPoint ofs = mapTo(topLevelWidget(), QPoint(0,0)); + int ofsX = ofs.x(); + int ofsY = ofs.y(); + + QPainter painter; + painter.begin(&bigBitmap); + painter.setBrush(color1); + painter.setPen(color1); + QRect rect = m_pluginLayout->geometry(); + rect.moveBy(ofsX, ofsY); + painter.drawRect(rect); + painter.drawPixmap(ofsX, ofsY, topPixmap); + painter.drawPixmap(ofsX, topPixmap.height()+ofsY, leftPixmap); + painter.drawPixmap(ofsX+insideSize.width() + leftPixmap.width(), + ofsY+ topPixmap.height(), rightPixmap); + painter.drawPixmap(ofsX, ofsY + height() - bottomPixmap.height(), + bottomPixmap); + + painter.end(); + topLevelWidget()->setMask(bigBitmap); +} + +void KSim::MainView::reparseConfig(bool emitReload, + const KSim::ChangedPluginList &list) +{ + kdDebug(2003) << "creating a new view" << endl; + + // Update the theme information for the theme classes + bool themeChanged = KSim::ThemeLoader::self().isDifferent(); + if (themeChanged) + KSim::ThemeLoader::self().reload(); + + const KSim::PluginList &pluginList = KSim::PluginLoader::self().pluginList(); + KSim::PluginList::ConstIterator plugin; + for (plugin = pluginList.begin(); plugin != pluginList.end(); ++plugin) { + if ((*plugin).configPage()) { + (*plugin).configPage()->saveConfig(); + KConfig *conf = (*plugin).configPage()->config(); + if (conf) conf->sync(); + } + + if (!(*plugin).isDifferent() && (*plugin).isEnabled()) { + kdDebug(2003) << "Recreating " << (*plugin).name() << "'s view" << endl; + kapp->processEvents(); + // Make sure the plugins background color is + // set to the correct theme color + if (themeChanged && (*plugin).view()) + KSim::ThemeLoader::self().themeColours((*plugin).view()); + + // Reload the config file and and recreate the plugins view + if ((*plugin).configPage() && (*plugin).configPage()->config()) + (*plugin).configPage()->config()->reparseConfiguration(); + + if ((*plugin).view()) { + (*plugin).view()->config()->reparseConfiguration(); + (*plugin).view()->reparseConfig(); + } + } + } + + ChangedPluginList::ConstIterator it; + for (it = list.begin(); it != list.end(); ++it) { + if ((*it).isDifferent()) { + if ((*it).isEnabled()) { // Go through the added/removed plugins and load/unload them + const KDesktopFile kdf((*it).filename()); + addPlugin(kdf); + m_prefDialog->createPage((*it).libName()); + } + else { + m_prefDialog->removePage((*it).libName()); + const KDesktopFile kdf((*it).filename()); + removePlugin(kdf); + } + } + } + + // reparse various non-plugin specific code + // recreate the plugin menu and the dock icon + KSim::BaseList::configureObjects(themeChanged); + if (themeChanged) + KSim::ThemeLoader::self().themeColours(this); + + m_sysinfo->createView(); + maskMainView(); + + m_topLevel->reparse(); + + if (emitReload) + emit reload(); + + kdDebug(2003) << "new view created" << endl; +} + +void KSim::MainView::addPlugins() +{ + QStringList locatedFiles = KGlobal::dirs()->findAllResources("data", "ksim/monitors/*.desktop"); + QStringList::ConstIterator it; + for (it = locatedFiles.begin(); it != locatedFiles.end(); ++it) + { + const KDesktopFile kdf(*it, true); + addPlugin(kdf); + } +} + +void KSim::MainView::addPlugin(const KDesktopFile &file, bool force) +{ + if (force || m_config->enabledMonitor(file.readEntry("X-KSIM-LIBRARY"))) + KSim::PluginLoader::self().loadPlugin(file); +} + +// provided for convenience +void KSim::MainView::removePlugin(const KDesktopFile &file) +{ + KSim::PluginLoader::self().unloadPlugin(file.readEntry("X-KSIM-LIBRARY").local8Bit()); +} + +void KSim::MainView::addMonitor(const KSim::Plugin &plugin) +{ + if (!plugin.view()) + return; + + plugin.view()->reparent(this, 0, QPoint(0, 0), true); + KSim::ThemeLoader::self().themeColours(plugin.view()); + +// int location = m_config->monitorLocation(plugin.libName()); +// if (location == -1) +// location = m_oldLocation + 1; +// else { +// location += 1; +// if (location > m_oldLocation) +// location = m_oldLocation + 1; +// } + +// kdDebug(2003) << "m_oldLocation: " << m_oldLocation << endl; +// kdDebug(2003) << "location: " << location << endl; + m_pluginLayout->addWidget(plugin.view()); + connect(plugin.view(), SIGNAL(runCommand(const QCString &)), + SLOT(runCommand(const QCString &))); + +// if (location > m_oldLocation) +// m_oldLocation = location; +} + +void KSim::MainView::runCommand(const QCString &name) +{ + if (name.isNull()) + return; + + kdDebug(2003) << "runCommand(" << name.mid(5) << ")" << endl; + QString exec = m_config->monitorCommand(name.mid(5)); + kdDebug(2003) << "exec is " << exec << endl; + KRun::runCommand(exec); +} + +void KSim::MainView::preferences() +{ + if (m_prefDialog == 0L) { + m_prefDialog = new KSim::ConfigDialog(m_config, this, "m_prefDialog"); + connect(m_prefDialog, SIGNAL(reparse(bool, const KSim::ChangedPluginList &)), + this, SLOT(reparseConfig(bool, const KSim::ChangedPluginList &))); + } + + m_prefDialog->exec(); + destroyPref(); +} + +void KSim::MainView::resizeEvent(QResizeEvent *re) +{ + QWidget::resizeEvent(re); + m_maskTimer.start(0, true); +} + +void KSim::MainView::paletteChange(const QPalette &) +{ + // Call true here to fool the KSim::Base pointers to + // think our theme changed, we can afford todo this + // since the palette doesn't change often. + KSim::BaseList::configureObjects(true); + + // Probably find a better way to do this + KSim::PluginList::ConstIterator it; + const KSim::PluginList &pluginList = KSim::PluginLoader::self().pluginList(); + for (it = pluginList.begin(); it != pluginList.end(); ++it) + KSim::ThemeLoader::self().themeColours((*it).view()); +} + +void KSim::MainView::destroyPref() +{ + if (m_prefDialog != 0L) { + kdDebug(2003) << "deleting KSimPref" << endl; + delete m_prefDialog; + m_prefDialog = 0L; + } +} + +QSize KSim::MainView::sizeHint(KPanelExtension::Position p, QSize) const +{ + int width = 0; + int height = 0; + + QLayoutItem *child; + for( QLayoutIterator it = m_pluginLayout->iterator(); + (child = it.current()) != 0; ++it) + { + QSize sz = child->minimumSize(); + if ((p == KPanelExtension::Right) || (p == KPanelExtension::Left)) + { + width = QMAX(width, sz.width()); + height += sz.height(); + } + else + { + width += sz.width(); + height = QMAX(height, sz.height()); + } + } + + width += m_leftFrame->minimumWidth() + m_rightFrame->minimumWidth(); + height += m_topFrame->minimumHeight() + m_bottomFrame->minimumHeight(); + + return QSize(width, height); +} + +void KSim::MainView::positionChange(KPanelExtension::Orientation o) +{ + if (o == KPanelExtension::Vertical) + m_pluginLayout->setDirection(QBoxLayout::TopToBottom); + else + m_pluginLayout->setDirection(QBoxLayout::LeftToRight); +} diff --git a/ksim/ksimview.h b/ksim/ksimview.h new file mode 100644 index 0000000..4bf7f1f --- /dev/null +++ b/ksim/ksimview.h @@ -0,0 +1,112 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#ifndef KSIMVIEW_H +#define KSIMVIEW_H + +#include <qwidget.h> +#include <qtimer.h> + +#include <dcopobject.h> + +#include <kpanelextension.h> +#include <kdelibs_export.h> + +class QBoxLayout; +class QHBoxLayout; +class QVBoxLayout; +class QPopupMenu; +class KDesktopFile; +class KConfig; + +namespace KSim +{ + class Sysinfo; + class Config; + class Plugin; + class Label; + class Frame; + class PanelExtension; + class ConfigDialog; + class ChangedPluginList; + + class KDE_EXPORT MainView : public QWidget, virtual public DCOPObject + { + Q_OBJECT + K_DCOP + public: + MainView(KConfig *config, bool loadPlugins, + KSim::PanelExtension *topLevel, + const char *name); + + ~MainView(); + + virtual void show(); + + KSim::Config *config() const; + void makeDirs(); + + QSize sizeHint(KPanelExtension::Position, QSize maxSize) const; + void positionChange(KPanelExtension::Orientation); + + k_dcop: + const QString &hostname() const; + virtual void maskMainView(); + + signals: + void reload(); + + public slots: + void reparseConfig(bool, const KSim::ChangedPluginList &); + void addPlugins(); + void addPlugin(const KDesktopFile &, bool force = false); + void removePlugin(const KDesktopFile &); + void addMonitor(const KSim::Plugin &); + void runCommand(const QCString &); + void preferences(); + void slotMaskMainView(); + + protected: + virtual void resizeEvent(QResizeEvent *); + virtual void paletteChange(const QPalette &); + + private slots: + void destroyPref(); + + private: + void cleanup(); + + KSim::Sysinfo *m_sysinfo; + KSim::Label *m_hostLabel; + KSim::Frame *m_leftFrame; + KSim::Frame *m_rightFrame; + KSim::Frame *m_topFrame; + KSim::Frame *m_bottomFrame; + KSim::PanelExtension *m_topLevel; + KSim::Config *m_config; + KSim::ConfigDialog *m_prefDialog; + QHBoxLayout *m_sizeLayout; + QVBoxLayout *m_subLayout; + QBoxLayout *m_pluginLayout; + QPoint m_mousePoint; + int m_oldLocation; + QTimer m_maskTimer; + }; +} +#endif // KSIMVIEW_H diff --git a/ksim/library/Makefile.am b/ksim/library/Makefile.am new file mode 100644 index 0000000..f3b834f --- /dev/null +++ b/ksim/library/Makefile.am @@ -0,0 +1,25 @@ +lib_LTLIBRARIES = libksimcore.la + +libksimcore_la_SOURCES = common.cpp themeloader.cpp \ + chart.cpp label.cpp \ + led.cpp progress.cpp \ + pluginglobal.cpp pluginloader.cpp \ + pluginmodule.cpp ksimconfig.cpp + +libksimcore_la_LDFLAGS = $(all_libraries) -version-info 1:0 -no-undefined +libksimcore_la_LIBADD = $(LIB_KDEUI) + +ksiminclude_HEADERS = common.h themeloader.h \ + chart.h label.h \ + led.h progress.h \ + pluginglobal.h pluginloader.h \ + pluginmodule.h themetypes.h \ + ksimconfig.h + + +ksimincludedir = $(includedir)/ksim + +INCLUDES= $(all_includes) + +METASOURCES = AUTO + diff --git a/ksim/library/chart.cpp b/ksim/library/chart.cpp new file mode 100644 index 0000000..38f0f17 --- /dev/null +++ b/ksim/library/chart.cpp @@ -0,0 +1,627 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#include "chart.h" +#include "chart.moc" + +#include <qrect.h> +#include <qpainter.h> +#include <qimage.h> +#include <qcolor.h> +#include <qtimer.h> +#include <qvaluelist.h> +#include <qbitmap.h> + +#include <kdebug.h> +#include <klocale.h> +#include <kglobalsettings.h> +#include <kconfig.h> + +#include <themeloader.h> +#include <led.h> +#include <ksimconfig.h> +#include "themetypes.h" + +class KSim::Chart::Timer +{ + public: + static void syncChart(KSim::Chart *chart) + { + if (!m_timer) { + m_timer = new QTimer; + m_timer->start(1000); + qAddPostRoutine(cleanup); + } + + QObject::connect(m_timer, SIGNAL(timeout()), + chart, SLOT(updateDisplay())); + } + + static void disconnect(KSim::Chart *chart) + { + if (!m_timer) + return; + + QObject::disconnect(m_timer, SIGNAL(timeout()), + chart, SLOT(updateDisplay())); + } + + private: + static void cleanup() + { + if (!m_timer) + return; + + delete m_timer; + m_timer = 0; + } + + static QTimer *m_timer; +}; + +QTimer *KSim::Chart::Timer::m_timer = 0; + +class KSim::Chart::Private +{ + public: + typedef QPair<int, int> ValuePair; + + QSize size; + int type; + bool showShadow; + bool showKrell; + QString inText; + QString outText; + QString title; + QPixmap chartPixmap; + QPixmap gridPixmap; + QPixmap graphData; + QColor mColour; + QColor sColour; + QColor dataInColour; + QColor dataOutColour; + Chart::LabelType labelType; + KSim::Label *krell; + // first will be data In and second will be data out + QValueList<ValuePair> values; + QValueList<int> maxValues; + int minValue; + int maxValue; + bool variableGraphs; +}; + +KSim::Chart::Chart(bool showKrell, int maxValue, + const QString &title, QWidget *parent, const char *name, + WFlags fl) : QWidget(parent, name, fl) +{ + init(showKrell, maxValue, title); +} + +KSim::Chart::Chart(bool showKrell, int maxValue, + QWidget *parent, const char *name, WFlags fl) + : QWidget(parent, name, fl) +{ + init(showKrell, maxValue, i18n("None")); +} + +KSim::Chart::~Chart() +{ + delete d->krell; + delete d; +} + +const QString &KSim::Chart::text(DataType type) const +{ + if (type == DataIn) + return d->inText; + + return d->outText; +} + +const QString &KSim::Chart::title() const +{ + return d->title; +} + +bool KSim::Chart::displayMeter() const +{ + return d->showKrell; +} + +int KSim::Chart::minValue() const +{ + return d->minValue; +} + +int KSim::Chart::maxValue() const +{ + return d->maxValue; +} + +int KSim::Chart::value(DataType dataType) const +{ + switch (dataType) { + case DataIn: + return d->values.first().first; + break; + case DataOut: + return d->values.first().second; + break; + } + + return 0; +} + +void KSim::Chart::setLabelType(LabelType labelType) +{ + d->labelType = labelType; + + // return if d->krell is not NULL and if the label type is the + // same or if showKrell is set to false + if ((d->krell && d->labelType == labelType) || !d->showKrell) + return; + + delete d->krell; + + switch (labelType) { + case Label: + d->krell = new KSim::Label(this); + break; + case Progress: + d->krell = new KSim::Progress(maxValue(), KSim::Types::None, + KSim::Progress::Panel, this); + break; + case Led: + d->krell = new KSim::LedLabel(maxValue(), KSim::Types::None, this); + break; + } + + int height = d->krell->height() - 2; + d->krell->setText(title()); + d->krell->setFixedSize(width(), height); + d->krell->move(0, d->size.height() - height); + d->krell->show(); +} + +KSim::Chart::LabelType KSim::Chart::labelType() const +{ + return d->labelType; +} + +void KSim::Chart::buildPixmaps() +{ + QImage image(themeLoader().current().chartPixmap()); + KSim::ThemeLoader::self().reColourImage(image); + d->chartPixmap.convertFromImage(image.smoothScale(chartSize())); + + // We need to reset the image data just + // incase the krellDataIn image doesn't exist + image.reset(); + image.load(themeLoader().current().gridPixmap()); + KSim::ThemeLoader::self().reColourImage(image); + d->gridPixmap.convertFromImage(image.smoothScale(chartSize().width(), 1)); + + // load these values here so we dont need to keep accessing them while + // painting to keep the cpu usage down + d->dataInColour = themeLoader().current().chartInColour(); + d->dataOutColour = themeLoader().current().chartOutColour(); + + image.reset(); + image.load(themeLoader().current().dataInPixmap()); + KSim::ThemeLoader::self().reColourImage(image); + if (!image.isNull()) { + d->dataInColour = image.smoothScale(chartSize()).pixel(2, 2); + kdDebug(2003) << className() << ": Using krellDataIn() = " + << themeLoader().current().dataInPixmap() << endl; + } + else { + kdDebug(2003) << className() << ": Using chartInColor() = " + << d->dataInColour.name() << endl; + } + + image.reset(); + image.load(themeLoader().current().dataOutPixmap()); + KSim::ThemeLoader::self().reColourImage(image); + if (!image.isNull()) { + d->dataOutColour = image.smoothScale(chartSize()).pixel(2, 2); + kdDebug(2003) << className() << ": Using krellDataOut() = " + << themeLoader().current().dataOutPixmap() << endl; + } + else { + kdDebug(2003) << className() << ": Using chartOutColor() = " + << d->dataOutColour.name() << endl; + } +} + +void KSim::Chart::configureObject(bool repaintWidget) +{ + QSize oldSize = sizeHint(); + KSim::Config::config()->setGroup("Misc"); + d->size = KSim::Config::config()->readSizeEntry("GraphSize"); + + if (d->krell && d->showKrell) { + int krellHeight = d->krell->fontMetrics().height() - 2; + d->size.setHeight(d->size.height() + krellHeight); + d->krell->setFixedHeight(krellHeight); + d->krell->move(0, d->size.height() - krellHeight); + d->krell->show(); + } + + // Update our geometry if we need to let any + // layout know about our sizeHint() change + if (oldSize != sizeHint()) { + // Using resize() here seems to be needed + resize(sizeHint()); + updateGeometry(); + } + + buildPixmaps(); + + setConfigValues(); + + if (repaintWidget) + update(); +} + +QSize KSim::Chart::sizeHint() const +{ + return d->size; +} + +QSize KSim::Chart::minimumSizeHint() const +{ + return sizeHint(); +} + +void KSim::Chart::resizeEvent(QResizeEvent *re) +{ + if (d->chartPixmap.size() != chartSize()) + buildPixmaps(); + QWidget::resizeEvent(re); +} + +void KSim::Chart::disableAutomaticUpdates() +{ + KSim::Chart::Timer::disconnect(this); +} + +void KSim::Chart::clear() +{ + d->values.clear(); + d->maxValues.clear(); + updateDisplay(); +} + +void KSim::Chart::setTitle(const QString &name) +{ + if (d->krell) { + d->title = name; + d->krell->setText(name); + } +} + +void KSim::Chart::setDisplayMeter(bool value) +{ + if (d->showKrell == value) + return; + + d->showKrell = value; + setLabelType(d->labelType); + + // delete the meter if value is false + if (!value) { + delete d->krell; + d->krell = 0; + } +} + +void KSim::Chart::setText(const QString &in, const QString &out) +{ + bool repaint = false; + + if (d->inText != in) { + repaint = true; + d->inText = in; + } + + if (d->outText != out) { + repaint = true; + d->outText = out; + } + + if (repaint) + update(); +} + +void KSim::Chart::setMinValue(int minValue) +{ + if (d->minValue == minValue) + return; + + d->minValue = minValue; + + if (d->krell && labelType() != Label) + static_cast<KSim::Progress *>(d->krell)->setMinValue(minValue); +} + +void KSim::Chart::setMaxValue(int maxValue) +{ + if (d->maxValue == maxValue) + return; + + d->maxValue = maxValue; + + if (d->krell && labelType() != Label) + static_cast<KSim::Progress *>(d->krell)->setMaxValue(maxValue); +} + +void KSim::Chart::setValue(int valueIn, int valueOut) +{ + d->values.prepend(qMakePair(range(valueIn), range(valueOut))); + + if (d->variableGraphs) { + d->maxValues.prepend(valueIn > valueOut ? valueIn : valueOut); + } + else { + if (valueIn > maxValue()) + setMaxValue(valueIn); + + if (valueOut > maxValue()) + setMaxValue(valueOut); + } + + if (d->krell && labelType() != Label) + static_cast<KSim::Progress *>(d->krell)->setValue(valueIn ? valueIn + : valueOut); + + // Remove the first entry from our lists to + // make sure we only have a list the size of + // our widgets width + if (d->values.count() == (uint)(width() + 1)) { + d->values.remove(--(d->values.end())); + d->maxValues.remove(--(d->maxValues.end())); + } + + if (d->krell && labelType() == Led) { + static_cast<KSim::LedLabel *>(d->krell)->toggle(KSim::Led::First); + static_cast<KSim::LedLabel *>(d->krell)->toggle(KSim::Led::Second); + } +} + +void KSim::Chart::setConfigValues() +{ + QFont newFont = font(); + bool repaint = themeLoader().current().fontColours(this, + newFont, d->mColour, d->sColour, d->showShadow); + + if (font() != newFont) + setFont(newFont); + + if (repaint) + update(); +} + +void KSim::Chart::extraTypeCall() +{ + setConfigValues(); +} + +QColor KSim::Chart::chartColour(const DataType &dataType, int, int) const +{ + switch (dataType) { + case DataIn: + return d->dataInColour; + break; + case DataOut: + return d->dataOutColour; + break; + } + + return QColor(); // avoid a g++ warning +} + +void KSim::Chart::paintEvent(QPaintEvent *) +{ + if (d->krell && labelType() == Led) { + static_cast<KSim::LedLabel *>(d->krell)->setOff(KSim::Led::First); + static_cast<KSim::LedLabel *>(d->krell)->setOff(KSim::Led::Second); + } + + const QSize &size = chartSize(); + QPixmap pixmap(size); + QPainter painter; + painter.begin(&pixmap, this); + + int location = size.height() / 5; + painter.drawPixmap(0, 0, d->chartPixmap); + // draw the plotted data onto the graph + painter.drawPixmap(0, 0, d->graphData); + painter.drawPixmap(0, location, d->gridPixmap); + painter.drawPixmap(0, location * 2, d->gridPixmap); + painter.drawPixmap(0, location * 3, d->gridPixmap); + painter.drawPixmap(0, location * 4, d->gridPixmap); + painter.drawPixmap(0, location * 5, d->gridPixmap); + + if (d->showShadow) { + painter.setPen(d->sColour); + location = (fontMetrics().height() / 2) + 5; + painter.drawText(3, location, d->inText); + if (!d->outText.isNull()) + painter.drawText(3, location * 2, d->outText); + } + + painter.setPen(d->mColour); + location = (fontMetrics().height() / 2) + 3; + painter.drawText(1, location, d->inText); + if (!d->outText.isNull()) + painter.drawText(1, location * 2, d->outText); + + painter.end(); + bitBlt(this, 0, 0, &pixmap); +} + +void KSim::Chart::fontChange(const QFont &) +{ + if (d->krell) + d->krell->setFont(font()); +} + +void KSim::Chart::updateDisplay() +{ + drawChart(); + update(); +} + +int KSim::Chart::yLocation(int value) const +{ + int krellHeight = (d->krell ? d->krell->height() : 0); + + int rangePos = maxValue() - minValue(); + int valuePos = value - minValue(); + + int returnValue = 0; + if (rangePos) + returnValue = (height() - krellHeight) * valuePos / rangePos; + + // Make sure we dont return a negative value + return returnValue >= 0 ? returnValue : 0; +} + +void KSim::Chart::drawChart() +{ + if (chartSize() != d->graphData.size()) + d->graphData.resize(chartSize()); + + if (d->variableGraphs) { + int maxValue = 0; + QValueList<int>::ConstIterator max; + for (max = d->maxValues.begin(); max != d->maxValues.end(); ++max) { + if ((*max) > maxValue) + maxValue = (*max); + } + + setMaxValue(maxValue); + } + + QPainter painter; + d->graphData.setMask(drawMask(&painter)); + painter.begin(&d->graphData, this); + + int position = width() - 1; + QValueList<Private::ValuePair>::ConstIterator it; + for (it = d->values.begin(); it != d->values.end(); ++it) { + // Draw the data In lines first if its higher than the data out lines + if ((*it).first >= (*it).second) { + drawIn(&painter, (*it).first, position); + drawOut(&painter, (*it).second, position); + } + else { + drawOut(&painter, (*it).second, position); + drawIn(&painter, (*it).first, position); + } + --position; + } + + painter.end(); +} + +QSize KSim::Chart::chartSize() const +{ + QSize sz(size()); + if (d->krell && d->showKrell) + sz.setHeight(sz.height() - d->krell->height()); + + return sz; +} + +QBitmap KSim::Chart::drawMask(QPainter *painter) +{ + QBitmap bitmap(chartSize(), true); + painter->begin(&bitmap, this); + painter->setPen(color1); + + int position = width() - 1; + QValueList<Private::ValuePair>::ConstIterator it; + for (it = d->values.begin(); it != d->values.end(); ++it) { + drawIn(painter, (*it).first, position, true); + drawOut(painter, (*it).second, position, true); + --position; + } + + painter->end(); + + return bitmap; +} + +void KSim::Chart::drawIn(QPainter *painter, int value, int pos, bool dontSet) +{ + if (!dontSet) { + painter->setPen(chartColour(DataIn)); + } + + int location = yLocation(value); + painter->moveTo(0, 0); + painter->drawLine(pos, d->graphData.size().height(), + pos, d->graphData.size().height() - location); +} + +void KSim::Chart::drawOut(QPainter *painter, int value, int pos, bool dontSet) +{ + if (!dontSet) { + painter->setPen(chartColour(DataOut)); + } + + int location = yLocation(value); + painter->moveTo(0, 0); + painter->drawLine(pos, d->graphData.size().height(), + pos, d->graphData.size().height() - location); +} + +int KSim::Chart::range(int value) const +{ + if (value > maxValue()) + return maxValue(); + + if (value < minValue()) + return minValue(); + + return value; +} + +void KSim::Chart::init(bool krell, int maxValue, const QString &title) +{ + setConfigString("StyleChart"); + setThemeConfigOnly(false); + setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed)); + + d = new Private; + KSim::Config::config()->setGroup("Misc"); + d->variableGraphs = KSim::Config::config()->readBoolEntry("UseVariableGraphs", true); + d->showKrell = krell; + d->krell = 0L; + d->title = title; + d->minValue = 0; + d->maxValue = 0; + + KSim::Chart::Timer::syncChart(this); + setBackgroundMode(NoBackground); + setLabelType(Label); + setMaxValue(maxValue); + configureObject(false); +} diff --git a/ksim/library/chart.h b/ksim/library/chart.h new file mode 100644 index 0000000..55f4426 --- /dev/null +++ b/ksim/library/chart.h @@ -0,0 +1,184 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#ifndef KSIM__CHART_H +#define KSIM__CHART_H + +#include <qwidget.h> +#include "common.h" + +#include <kdemacros.h> + +class QColor; + +namespace KSim +{ + /** + * provides a graph displaying data onscreen using gkrellm themes + * @author Robbie Ward <linuxphreak@gmx.co.uk> + */ + class KDE_EXPORT Chart : public QWidget, public KSim::Base + { + Q_OBJECT + public: + enum DataType { DataIn = 0, DataOut }; + enum LabelType { Label = 0, Progress, Led }; + /** + * Constructs a KSim::Chart. + * + * @param displayMeter is if the krellbar should be shown + * @param minValue is the minimum value to show + * @param maxValue is the maximum value to show + * @param title is the title off the krell bar (if enabled) + * @param parent is the parent widget + */ + Chart(bool displayMeter, int maxValue, + const QString &title, QWidget *parent, + const char *name = 0, WFlags fl = 0); + /** + * Constructs a KSim::Chart. + * + * @param showKrell is if the krellbar should be shown + * @param minValue is the minimum value to show + * @param maxValue is the maximum value to show + * @param parent is the parent widget + */ + Chart(bool displayMeter, int maxValue, + QWidget *parent, const char *name = 0, + WFlags fl = 0); + /** + * destructs KSim::Chart + */ + virtual ~Chart(); + + /** + * returns the current text of the chart + */ + const QString &text(DataType type) const; + /** + * @return the title of the chart + */ + const QString &title() const; + /** + * @return true if the meter is enabled + */ + bool displayMeter() const; + /** + * @return the minimum value + */ + int minValue() const; + /** + * @return the minimum value + */ + int maxValue() const; + /** + * @return the current value + */ + int value(DataType dataType) const; + /** + * sets the type of the label that will appear under the graph + */ + void setLabelType(LabelType labelType); + /** + * @return the current label type, one of: Label, Progress, Led + */ + LabelType labelType() const; + + /** + * reimplemented for internal reasons + */ + virtual void configureObject(bool repaintWidget = true); + + /** + * reimplemented for internal reasons + */ + QSize sizeHint() const; + /** + * reimplemented for internal reasons + */ + QSize minimumSizeHint() const; + + void disableAutomaticUpdates(); + + public slots: + /** + * Cleats the graphs contents + */ + void clear(); + /** + * sets the title of the chart, this function returns if + * the optional krell widget is disabled + */ + void setTitle(const QString &); + /** + * turns the meter on and off + */ + void setDisplayMeter(bool); + /** + * sets the current text that apears in the top left hand corner + */ + void setText(const QString &in, const QString &out = QString::null); + /** + * Sets the minimum value the graph will display + */ + void setMinValue(int); + /** + * Sets the maximum value the graph will display + */ + void setMaxValue(int); + /** + * sets the value of the graph + */ + void setValue(int valueIn, int valueOut = 0); + + protected: + /** + * Set the config values depending on the chart type + */ + void setConfigValues(); + /** + * reimplemented for internal reasons + */ + virtual void extraTypeCall(); + + QColor chartColour(const DataType &dataType, int x = 1, int y = 1) const; + virtual void paintEvent(QPaintEvent *); + virtual void fontChange(const QFont &); + virtual void resizeEvent(QResizeEvent *re); + + protected slots: + void updateDisplay(); + + private: + void buildPixmaps(); + int yLocation(int) const; + void drawChart(); + QSize chartSize() const; + QBitmap drawMask(QPainter *); + void drawIn(QPainter *, int, int, bool = false); + void drawOut(QPainter *, int, int, bool = false); + int range(int) const; + void init(bool, int, const QString &); + + class Timer; + class Private; + Private *d; + }; +} +#endif diff --git a/ksim/library/common.cpp b/ksim/library/common.cpp new file mode 100644 index 0000000..3e714c6 --- /dev/null +++ b/ksim/library/common.cpp @@ -0,0 +1,102 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#include "common.h" +#include <kdebug.h> + +#include <themeloader.h> +#include "themetypes.h" +#include "../baselist.h" + +class KSim::Base::Private +{ + public: + int type; + bool theme; + QString string; +}; + +KSim::Base::Base() +{ + KSim::BaseList::add(this); + + d = new Base::Private; + d->type = KSim::Types::None; + d->theme = true; +} + +KSim::Base::Base(int type) +{ + KSim::BaseList::add(this); + + d = new Base::Private; + d->type = type; + d->theme = true; +} + +KSim::Base::~Base() +{ + if (!KSim::BaseList::remove(this)) + kdError() << "While trying to remove " << this << " from the list" << endl; + delete d; +} + +bool KSim::Base::isThemeConfigOnly() const +{ + return d->theme; +} + +void KSim::Base::setType(int type) +{ + if (d->type == type) + return; + + d->type = type; + extraTypeCall(); +} + +int KSim::Base::type() const +{ + return d->type; +} + +void KSim::Base::setConfigString(const QString &string) +{ + d->string = string; +} + +const QString &KSim::Base::configString() const +{ + return d->string; +} + +void KSim::Base::extraTypeCall() +{ +} + +KSim::ThemeLoader &KSim::Base::themeLoader() const +{ + // Provided for convenience + return KSim::ThemeLoader::self(); +} + +void KSim::Base::setThemeConfigOnly(bool value) +{ + d->theme = value; +} diff --git a/ksim/library/common.h b/ksim/library/common.h new file mode 100644 index 0000000..3f53f7a --- /dev/null +++ b/ksim/library/common.h @@ -0,0 +1,134 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#ifndef KSIM__COMMON_H +#define KSIM__COMMON_H + +#define KSIM_VERSION 110 +#define KSIM_VERSION_STRING "1.1.0" + +#include <qstring.h> +#include <kdemacros.h> + +/** + * namespace for common ksim entries + * + * @author Robbie Ward <linuxphreak@gmx.co.uk> + */ +namespace KSim +{ + // a few forward declares + class ThemeLoader; + class Theme; + class PluginLoader; + class PluginList; + class Plugin; + class PluginObject; + class PluginView; + class PluginPage; + + /** + * class that all widgets (library dir only) HAVE to inherit + * if they want to change items on ksim configuration reload + * + * any class that inherits this must re-implement + * the configureObject() function. + * + * example: + * <pre> + * #include <qwidget.h> + * #include <ksim/common.h> + * + * class Test : public QWidget, virtual public KSim::Base + * { + * public: + * Test(QWidget *parent, const char *name) : QWidget(parent, name) + * { + * } + * ~Test() {} + * + * void configureObject(bool repaintWidget) + * { + * // Re-Create view code here + * } + * }; + * </pre> + * @short base class for widgets + * @author Robbie Ward <linuxphreak@gmx.co.uk> + */ + class KDE_EXPORT Base + { + public: + Base(); + Base(int type); + virtual ~Base(); + + /** + * Reimplement this to change theme images/locations etc + */ + virtual void configureObject(bool = true) = 0; + /** + * returns true if configureObject has been setup + * to contain only theme configuration + * @see #setThemeConfigOnly + */ + bool isThemeConfigOnly() const; + /** + * sets the theme type + */ + void setType(int type); + /** + * @return the theme type, eg host, mem, swap etc + */ + int type() const; + /** + * Set the config entry key to look for when reading gkrellmrc + */ + void setConfigString(const QString &string); + /** + * @return the config entry to look for when reading theme files + */ + const QString &configString() const; + + protected: + /** + * reimplement this function if you want setType() + * to call extra information + */ + virtual void extraTypeCall(); + /** + * @return the current KSim::ThemeLoader instance + */ + KSim::ThemeLoader &themeLoader() const; + /** + * set this to false if you want KSim to call your KSim::Base + * configureObject() when KSim's configuration has changed + * even if the theme settings are the same. The default is true + */ + void setThemeConfigOnly(bool); + + private: + Base(const Base &rhs); + Base &operator=(const Base &rhs); + + class Private; + Private *d; + }; +} +#endif diff --git a/ksim/library/ksimconfig.cpp b/ksim/library/ksimconfig.cpp new file mode 100644 index 0000000..9f70890 --- /dev/null +++ b/ksim/library/ksimconfig.cpp @@ -0,0 +1,427 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#include <kstandarddirs.h> +#include <kconfig.h> +#include <kglobal.h> + +#include "ksimconfig.h" +#include "themeloader.h" + +KConfig *KSim::Config::mainConfig = 0; + +KSim::Config::Config(KConfig *config) +{ + mainConfig = config; +} + +KSim::Config::~Config() +{ +} + +KConfig *KSim::Config::config() +{ + return mainConfig; +} + +int KSim::Config::width(int defaultWidth) const +{ + mainConfig->setGroup("General Options"); + int savedWidth = mainConfig->readNumEntry("Width"); + if (savedWidth == -1) + return defaultWidth; + + return savedWidth; +} + +void KSim::Config::setWidth(int width) +{ + mainConfig->setGroup("General Options"); + mainConfig->writeEntry("Width", width); + mainConfig->sync(); +} + +bool KSim::Config::enabledMonitor(const QString &entry) const +{ + mainConfig->setGroup("Monitors"); + return mainConfig->readBoolEntry(entry, false); +} + +void KSim::Config::setEnabledMonitor(const QString &entry, bool enabled) +{ + mainConfig->setGroup("Monitors"); + mainConfig->writeEntry(entry, enabled); + mainConfig->sync(); +} + +QString KSim::Config::monitorCommand(const QString &entry) const +{ + mainConfig->setGroup("Monitors"); + return mainConfig->readPathEntry(entry + "_command"); +} + +void KSim::Config::setMonitorCommand(const QString &entry, + const QString &command) +{ + mainConfig->setGroup("Monitors"); + mainConfig->writePathEntry(entry + "_command", command); + mainConfig->sync(); +} + +int KSim::Config::monitorLocation(const QString &entry) +{ + mainConfig->setGroup("Monitors"); + return mainConfig->readNumEntry(entry + "_location", -1); +} + +void KSim::Config::setMonitorLocation(const QString &entry, int location) +{ + mainConfig->setGroup("Monitors"); + mainConfig->writeEntry(entry + "_location", location); + mainConfig->sync(); +} + +bool KSim::Config::displayFqdn() const +{ + mainConfig->setGroup("Misc"); + return mainConfig->readBoolEntry("DisplayFqdn", true); +} + +void KSim::Config::setDisplayFqdn(bool value) +{ + mainConfig->setGroup("Misc"); + mainConfig->writeEntry("DisplayFqdn", value); + mainConfig->sync(); +} + +bool KSim::Config::showDock() const +{ + mainConfig->setGroup("Misc"); + return mainConfig->readBoolEntry("showDock", true); +} + +void KSim::Config::setShowDock(bool showDock) +{ + mainConfig->setGroup("Misc"); + mainConfig->writeEntry("showDock", showDock); + mainConfig->sync(); +} + +bool KSim::Config::savePos() const +{ + mainConfig->setGroup("Misc"); + return mainConfig->readBoolEntry("savePos", false); +} + +void KSim::Config::setSavePos(bool savePos) +{ + mainConfig->setGroup("Misc"); + mainConfig->writeEntry("savePos", savePos); + mainConfig->sync(); +} + +bool KSim::Config::stayOnTop() const +{ + mainConfig->setGroup("Misc"); + return mainConfig->readBoolEntry("stayOnTop", false); +} + +void KSim::Config::setStayOnTop(bool stayOnTop) +{ + mainConfig->setGroup("Misc"); + mainConfig->writeEntry("stayOnTop", stayOnTop); + mainConfig->sync(); +} + +QPoint KSim::Config::position(const QPoint &defaultPos) const +{ + mainConfig->setGroup("Misc"); + return mainConfig->readPointEntry("ksimPosition", &defaultPos); +} + +void KSim::Config::setPosition(const QPoint &pos) +{ + mainConfig->setGroup("Misc"); + mainConfig->writeEntry("ksimPosition", pos); + mainConfig->sync(); +} + +QSize KSim::Config::graphSize() const +{ + mainConfig->setGroup("Misc"); + return mainConfig->readSizeEntry("GraphSize"); +} + +void KSim::Config::setGraphSize(const QSize &size) +{ + mainConfig->setGroup("Misc"); + mainConfig->writeEntry("GraphSize", size); + mainConfig->sync(); +} + +QString KSim::Config::uptimeFormat() const +{ + return uptimeFormatList()[uptimeItem()]; +} + +int KSim::Config::uptimeItem() const +{ + mainConfig->setGroup("Misc"); + return mainConfig->readNumEntry("UptimeItem", 0); +} + +QStringList KSim::Config::uptimeFormatList() const +{ + mainConfig->setGroup("Misc"); + return mainConfig->readListEntry("UptimeFormat"); +} + +void KSim::Config::setUptimeFormat(const QStringList &uptimeFormat) +{ + mainConfig->setGroup("Misc"); + mainConfig->writeEntry("UptimeFormat", uptimeFormat); + mainConfig->sync(); +} + +void KSim::Config::setUptimeItem(int item) +{ + mainConfig->setGroup("Misc"); + mainConfig->writeEntry("UptimeItem", item); + mainConfig->sync(); +} + +QString KSim::Config::memoryFormat() const +{ + return memoryFormatList()[memoryItem()]; +} + +int KSim::Config::memoryItem() const +{ + mainConfig->setGroup("Misc"); + return mainConfig->readNumEntry("MemoryItem", 0); +} + +QStringList KSim::Config::memoryFormatList() const +{ + mainConfig->setGroup("Misc"); + return mainConfig->readListEntry("MemoryFormat"); +} + +void KSim::Config::setMemoryFormat(const QStringList &memoryFormat) +{ + mainConfig->setGroup("Misc"); + mainConfig->writeEntry("MemoryFormat", memoryFormat); + mainConfig->sync(); +} + +void KSim::Config::setMemoryItem(int item) +{ + mainConfig->setGroup("Misc"); + mainConfig->writeEntry("MemoryItem", item); + mainConfig->sync(); +} + +QString KSim::Config::swapFormat() const +{ + mainConfig->setGroup("Misc"); + return swapFormatList()[swapItem()]; +} + +int KSim::Config::swapItem() const +{ + mainConfig->setGroup("Misc"); + return mainConfig->readNumEntry("SwapItem", 0); +} + +QStringList KSim::Config::swapFormatList() const +{ + mainConfig->setGroup("Misc"); + return mainConfig->readListEntry("SwapFormat"); +} + +void KSim::Config::setSwapFormat(const QStringList &swapFormat) +{ + mainConfig->setGroup("Misc"); + mainConfig->writeEntry("SwapFormat", swapFormat); + mainConfig->sync(); +} + +void KSim::Config::setSwapItem(int item) +{ + mainConfig->setGroup("Misc"); + mainConfig->writeEntry("SwapItem", item); + mainConfig->sync(); +} + +bool KSim::Config::showTime() const +{ + mainConfig->setGroup("Misc"); + return mainConfig->readBoolEntry("ShowTime", false); +} + +void KSim::Config::setShowTime(bool time) +{ + mainConfig->setGroup("Misc"); + mainConfig->writeEntry("ShowTime", time); + mainConfig->sync(); +} + +bool KSim::Config::show24hour() const +{ + mainConfig->setGroup("Misc"); + return mainConfig->readBoolEntry("Show24hour", true); +} + +void KSim::Config::setShow24hour(bool _24hour) +{ + mainConfig->setGroup("Misc"); + mainConfig->writeEntry("Show24hour", _24hour); + mainConfig->sync(); +} + +bool KSim::Config::showDate() const +{ + mainConfig->setGroup("Misc"); + return mainConfig->readBoolEntry("ShowDate", false); +} + +void KSim::Config::setShowDate(bool date) +{ + mainConfig->setGroup("Misc"); + mainConfig->writeEntry("ShowDate", date); + mainConfig->sync(); +} + +bool KSim::Config::showUptime() const +{ + mainConfig->setGroup("Misc"); + return mainConfig->readBoolEntry("ShowUptime", true); +} + +void KSim::Config::setShowUptime(bool uptime) +{ + mainConfig->setGroup("Misc"); + mainConfig->writeEntry("ShowUptime", uptime); + mainConfig->sync(); +} + +bool KSim::Config::showMemory() const +{ + mainConfig->setGroup("Misc"); + return mainConfig->readBoolEntry("ShowMemory", true); +} + +void KSim::Config::setShowMemory(bool memory) +{ + mainConfig->setGroup("Misc"); + mainConfig->writeEntry("ShowMemory", memory); + mainConfig->sync(); +} + +bool KSim::Config::showSwap() const +{ + mainConfig->setGroup("Misc"); + return mainConfig->readBoolEntry("ShowSwap", true); +} + +void KSim::Config::setShowSwap(bool swap) +{ + mainConfig->setGroup("Misc"); + mainConfig->writeEntry("ShowSwap", swap); + mainConfig->sync(); +} + +bool KSim::Config::showProcs() const +{ + mainConfig->setGroup("Misc"); + return mainConfig->readBoolEntry("ShowProcs", false); +} + +void KSim::Config::setShowProcs(bool procs) +{ + mainConfig->setGroup("Misc"); + mainConfig->writeEntry("ShowProcs", procs); + mainConfig->sync(); +} + +QString KSim::Config::themeUrl() const +{ + return KSim::ThemeLoader::currentUrl(); +} + +QString KSim::Config::themeName() const +{ + return KSim::ThemeLoader::currentName(); +} + +void KSim::Config::setThemeName(const QString &name) +{ + mainConfig->setGroup("Theme"); + mainConfig->writeEntry("Name", name); + mainConfig->sync(); +} + +int KSim::Config::themeAlt() const +{ + return KSim::ThemeLoader::currentAlternative(); +} + +void KSim::Config::setThemeAlt(int alt) +{ + mainConfig->setGroup("Theme"); + mainConfig->writeEntry("Alternative", alt); + mainConfig->sync(); +} + +QFont KSim::Config::themeFont() const +{ + return KSim::ThemeLoader::currentFont(); +} + +void KSim::Config::setThemeFont(const QFont &font) +{ + mainConfig->setGroup("Theme"); + mainConfig->writeEntry("Font", font); + mainConfig->sync(); +} + +int KSim::Config::themeFontItem() const +{ + return KSim::ThemeLoader::currentFontItem(); +} + +void KSim::Config::setThemeFontItem(int item) +{ + mainConfig->setGroup("Theme"); + mainConfig->writeEntry("FontItem", item); + mainConfig->sync(); +} + +bool KSim::Config::reColourThemes() const +{ + mainConfig->setGroup("Misc"); + return mainConfig->readBoolEntry("ReColourTheme", false); +} + +void KSim::Config::setReColourThemes(bool value) +{ + mainConfig->setGroup("Misc"); + mainConfig->writeEntry("ReColourTheme", value); + mainConfig->sync(); +} diff --git a/ksim/library/ksimconfig.h b/ksim/library/ksimconfig.h new file mode 100644 index 0000000..0208b18 --- /dev/null +++ b/ksim/library/ksimconfig.h @@ -0,0 +1,109 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#ifndef KSIMCONFIG_H +#define KSIMCONFIG_H + +#include <qstringlist.h> +#include <qpoint.h> +#include <qfont.h> + +#include <kdemacros.h> + +class KConfig; + +namespace KSim +{ + /** + * @internal + */ + class KDE_EXPORT Config + { + public: + Config(KConfig *config); + ~Config(); + + static KConfig *config(); + + int width(int defaultWidth) const; + void setWidth(int width); + bool enabledMonitor(const QString &) const; + void setEnabledMonitor(const QString &, bool); + QString monitorCommand(const QString &) const; + void setMonitorCommand(const QString &, const QString &); + int monitorLocation(const QString &); + void setMonitorLocation(const QString &, int); + bool displayFqdn() const; + void setDisplayFqdn(bool); + bool showDock() const; + void setShowDock(bool); + bool savePos() const; + void setSavePos(bool); + bool stayOnTop() const; + void setStayOnTop(bool); + QPoint position(const QPoint &) const; + void setPosition(const QPoint &); + QSize graphSize() const; + void setGraphSize(const QSize &); + QString uptimeFormat() const; + void setUptimeFormat(const QStringList &); + int uptimeItem() const; + void setUptimeItem(int); + QStringList uptimeFormatList() const; + QString memoryFormat() const; + void setMemoryFormat(const QStringList &); + int memoryItem() const; + void setMemoryItem(int); + QStringList memoryFormatList() const; + QString swapFormat() const; + void setSwapFormat(const QStringList &); + int swapItem() const; + void setSwapItem(int); + QStringList swapFormatList() const; + bool showTime() const; + void setShowTime(bool); + bool show24hour() const; + void setShow24hour(bool); + bool showDate() const; + void setShowDate(bool); + bool showUptime() const; + void setShowUptime(bool); + bool showMemory() const; + void setShowMemory(bool); + bool showSwap() const; + void setShowSwap(bool); + bool showProcs() const; + void setShowProcs(bool); + QString themeUrl() const; + QString themeName() const; + void setThemeName(const QString &); + int themeAlt() const; + void setThemeAlt(int); + QFont themeFont() const; + void setThemeFont(const QFont &); + int themeFontItem() const; + void setThemeFontItem(int); + bool reColourThemes() const; + void setReColourThemes(bool); + + private: + static KConfig *mainConfig; + }; +} +#endif diff --git a/ksim/library/label.cpp b/ksim/library/label.cpp new file mode 100644 index 0000000..91e7621 --- /dev/null +++ b/ksim/library/label.cpp @@ -0,0 +1,301 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#include "label.h" +#include "label.moc" +#include <ksimconfig.h> +#include "themetypes.h" + +#include <qpainter.h> +#include <qstyle.h> +#include <qstylesheet.h> +#include <qsimplerichtext.h> +#include <qcursor.h> +#include <qpixmap.h> +#include <qimage.h> + +#include <themeloader.h> +#include <kdebug.h> +#include <kglobal.h> +#include <kglobalsettings.h> +#include <kconfig.h> + +class KSim::Label::Private +{ + public: + QColor mColour; + QColor sColour; + QRect loc; + QRect shad; + QString text; + QImage meterImage; + QPixmap background; + QPixmap sidePixmap; + bool showShadow; +}; + +KSim::Label::Label(QWidget *parent, const char *name, WFlags fl) + : QWidget(parent, name, fl) +{ + initWidget(KSim::Types::None); +} + +KSim::Label::Label(int type, QWidget *parent, const char *name, + WFlags fl) : QWidget(parent, name, fl) +{ + initWidget(type); +} + +KSim::Label::Label(int type, const QString &text, QWidget *parent, + const char *name, WFlags fl) : QWidget(parent, name, fl) +{ + initWidget(type); + setText(text); +} + +KSim::Label::~Label() +{ + delete d; +} + +const QString &KSim::Label::text() const +{ + return d->text; +} + +void KSim::Label::configureObject(bool repaintWidget) +{ + QString image = themeLoader().current().meterPixmap(type(), false); + if (image.isEmpty()) + image = themeLoader().current().panelPixmap(type()); + + d->meterImage.load(image); + KSim::ThemeLoader::self().reColourImage(d->meterImage); + d->background = d->meterImage.smoothScale(size()); + QSize oldSize = sizeHint(); + + setConfigValues(); + relayoutLabel(oldSize, repaintWidget); +} + +void KSim::Label::setPixmap(const QPixmap &pixmap) +{ + if (pixmap.serialNumber() == d->sidePixmap.serialNumber()) + return; + + QSize oldSize = sizeHint(); + d->sidePixmap = pixmap; + + relayoutLabel(oldSize); +} + +const QPixmap &KSim::Label::pixmap() const +{ + return d->sidePixmap; +} + +QSize KSim::Label::sizeHint() const +{ + int width = fontMetrics().size(SingleLine, text()).width(); + if (!pixmap().isNull()) + width += pixmap().width() + 5; + + int height = fontMetrics().height() + 4; + if (!pixmap().isNull() && pixmap().height() > height) + height = pixmap().height(); + + return QSize(width, height); +} + +QSize KSim::Label::minimumSizeHint() const +{ + return sizeHint(); +} + +void KSim::Label::clear() +{ + setText(QString::null); +} + +void KSim::Label::setText(const QString &text) +{ + if (text == d->text) + return; // If the text is the same, no need to repaint etc + + QSize oldSize = sizeHint(); + // set the text of our widget and repaint + d->text = text; + relayoutLabel(oldSize); +} + +void KSim::Label::extraTypeCall() +{ + d->meterImage.load(themeLoader().current().meterPixmap(type())); + setConfigValues(); +} + +void KSim::Label::setShowShadow(bool show) +{ + d->showShadow = show; +} + +bool KSim::Label::showShadow() const +{ + return d->showShadow; +} + +void KSim::Label::setTextColour(const QColor &color) +{ + d->mColour = color; +} + +const QColor &KSim::Label::textColour() const +{ + return d->mColour; +} + +void KSim::Label::setShadowColour(const QColor &color) +{ + d->sColour = color; +} + +const QColor &KSim::Label::shadowColour() const +{ + return d->sColour; +} + +void KSim::Label::setConfigValues() +{ + QFont newFont = font(); + bool repaint = themeLoader().current().fontColours(this, + newFont, d->mColour, d->sColour, d->showShadow); + + if (font() != newFont) + setFont(newFont); + + if (repaint) + update(); +} + +void KSim::Label::paintEvent(QPaintEvent *) +{ + QPainter painter; + painter.begin(this); + + // paint our background pixmap onto the widget + painter.drawPixmap(0, 0, d->background); + + drawPixmap(&painter, d->loc, pixmap()); + if (d->showShadow) { // draw the shadow text on the image + drawText(&painter, d->shad, d->sColour, d->text); + } + + // draw the label text onto the widget + painter.setPen(d->mColour); + drawText(&painter, d->loc, d->mColour, d->text); + painter.end(); +} + +void KSim::Label::resizeEvent(QResizeEvent *ev) +{ + // set the location of where the shadow'ed text will be drawn + d->shad.setWidth(ev->size().width() + 3); + d->shad.setHeight(ev->size().height() + 3); + + // set the location of where the text will be drawn + d->loc.setWidth(ev->size().width()); + d->loc.setHeight(ev->size().height()); + + d->background = d->meterImage.smoothScale(ev->size()); +} + +void KSim::Label::drawText(QPainter *painter, const QRect &rect, + const QColor &color, const QString &text) +{ + QRect location(rect); + if (!pixmap().isNull()) + location.setX(pixmap().width() + 5); + + style().drawItem(painter, location, AlignCenter, colorGroup(), true, + 0, text, -1, &color); +} + +void KSim::Label::drawPixmap(QPainter *painter, const QRect &rect, + const QPixmap &pixmap) +{ + QRect location(rect); + location.setWidth(pixmap.width()); + + style().drawItem(painter, location, AlignCenter, colorGroup(), true, + pixmap.isNull() ? 0 : &pixmap, QString::null); +} + +void KSim::Label::setTextLocation(const QRect &rect) +{ + d->loc = rect; +} + +const QRect &KSim::Label::textLocation() const +{ + return d->loc; +} + +void KSim::Label::setShadowLocation(const QRect &rect) +{ + d->shad = rect; +} + +const QRect &KSim::Label::shadowLocation() const +{ + return d->shad; +} + +void KSim::Label::setThemePixmap(const QString &image) +{ + QSize oldSize = sizeHint(); + d->meterImage.reset(); + d->meterImage.load(image); + KSim::ThemeLoader::self().reColourImage(d->meterImage); + d->background = d->meterImage.smoothScale(size()); + relayoutLabel(oldSize); +} + +void KSim::Label::relayoutLabel(const QSize &old, bool repaint) +{ + if (sizeHint() != old) { + updateGeometry(); + } + + if (repaint) + update(); +} + +void KSim::Label::initWidget(int type) +{ + d = new Private; + setType(type); + setConfigString("StyleMeter"); + + // try to reduce flicker as much as possible + setBackgroundMode(NoBackground); + setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding, + QSizePolicy::Fixed)); + + configureObject(); +} diff --git a/ksim/library/label.h b/ksim/library/label.h new file mode 100644 index 0000000..1c750f2 --- /dev/null +++ b/ksim/library/label.h @@ -0,0 +1,210 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#ifndef KSIM__LABEL_H +#define KSIM__LABEL_H + +#include <qwidget.h> +#include "common.h" + +#include <kdemacros.h> + +namespace KSim +{ + /** + * A widget that provides a text or image display + * which supports themes from gkrellm + * + * @short Label widget + * @author Robbie Ward <linuxphreak@gmx.co.uk> + */ + class KDE_EXPORT Label : public QWidget, public KSim::Base + { + Q_OBJECT + public: + /** + * Constructs a KSim::Label. + * + * @param parent is the parent widget + * + * Example usage: + * <pre> + * KSim::Label *label = new KSim::Label(this); + * </pre> + * To create a KSim::Label with the normal theme look + * @see KSim::ThemeLoader + */ + Label(QWidget *parent, const char *name = 0, WFlags fl = 0); + /** + * Constructs a KSimLabel. + * + * @param type is the theme type + * @param parent is the parent widget + * + * Example usage: + * <pre> + * KSim::Label *label = new KSim::Label(KSim::Types::None, this); + * </pre> + * To create a KSim::Label with the normal theme look, + * NOTE: this is the same as the KSim::Label(QWidget *, const char *, WFlags) ctor + * @see KSim::ThemeLoader + */ + Label(int type, QWidget *parent, const char *name = 0, WFlags fl = 0); + /** + * Constructs a KSim::Label. + * + * @param type is the theme type + * @param text is the default text to display + * @param parent is the parent widget + * + * Example usage: + * <pre> + * KSim::Label *label = new KSim:Label(KSim::Types::Host, "test label", this); + * </pre> + * To create a KSim::Label with the theme look of host + * @see KSim::ThemeLoader + */ + Label(int type, const QString &text, + QWidget *parent, const char *name = 0, WFlags fl = 0); + /** + * destructs KSim::Label. + */ + virtual ~Label(); + + /** + * returns the current text of the label + * @see #setText + */ + const QString &text() const; + /** + * recreates the labels look & feel + */ + virtual void configureObject(bool repaintWidget = true); + /** + * sets a pixmap for the label + */ + void setPixmap(const QPixmap &pixmap); + /** + * @return the side pixmap + */ + const QPixmap &pixmap() const; + /** + * reimplemented for internal reasons + */ + virtual QSize sizeHint() const; + /** + * reimplemented for internal reasons + */ + virtual QSize minimumSizeHint() const; + + public slots: + /** + * clears the current text in the label + */ + void clear(); + /** + * sets the current label of the widget to @ref text + * @see text() + */ + void setText(const QString &text); + + protected: + /** + * reimplemented for internal reasons + */ + virtual void extraTypeCall(); + /** + * set wether the shadow should be shown or not + */ + void setShowShadow(bool show); + /** + * @return true if the shadow is to be shown, else false + */ + bool showShadow() const; + /** + * Set the text color + */ + void setTextColour(const QColor &color); + /** + * @return the text color + */ + const QColor &textColour() const; + /** + * Set the shadow color + */ + void setShadowColour(const QColor &color); + /** + * @return the shadow color + */ + const QColor &shadowColour() const; + /** + * Set the config values depending on the chart type + */ + void setConfigValues(); + /** + * reimplemented for internal reasons + */ + virtual void paintEvent(QPaintEvent *); + /** + * reimplemented for internal reasons + */ + virtual void resizeEvent(QResizeEvent *); + /** + * draw the text onto the label + */ + void drawText(QPainter *painter, const QRect &rect, + const QColor &color, const QString &text); + /** + * draw the pixmap onto the label + */ + void drawPixmap(QPainter *painter, + const QRect &rect, const QPixmap &pixmap); + /** + * sets the location of the text + */ + void setTextLocation(const QRect &rect); + /** + * @return the location of the text + */ + const QRect &textLocation() const; + /** + * sets the location of the shadow text + */ + void setShadowLocation(const QRect &rect); + /** + * @return the location of the shadow text + */ + const QRect &shadowLocation() const; + /** + * sets the background image to be painted + */ + void setThemePixmap(const QString &image); + void relayoutLabel(const QSize &old, bool repaint = true); + + private: + /** + * initiates the widget + */ + void initWidget(int type); + + class Private; + Private *d; + }; +} +#endif diff --git a/ksim/library/led.cpp b/ksim/library/led.cpp new file mode 100644 index 0000000..8d0c88d --- /dev/null +++ b/ksim/library/led.cpp @@ -0,0 +1,349 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#include "led.h" +#include "led.moc" + +#include <qimage.h> +#include <qpainter.h> +#include <qfile.h> +#include <qbitmap.h> + +#include <kdebug.h> +#include <kpixmapsplitter.h> + +#include <themeloader.h> +#include "themetypes.h" + +class KSim::Led::Private +{ + public: + KPixmapSplitter splitter; + QPixmap pixmap; + QString imageName; + KSim::Led::Type type; + bool toggled; +}; + +KSim::Led::Led() : QPixmap() +{ + d = new Private; + + d->type = First; + d->toggled = false; + + setPixmap(KSim::ThemeLoader::self().current().ledPixmap(KSim::Types::Net)); + setOff(); +} + +KSim::Led::Led(Type type, const QString &imageName) : QPixmap() +{ + d = new Private; + + d->type = type; + d->toggled = false; + + setPixmap(imageName); + setOff(); +} + +KSim::Led::~Led() +{ + delete d; +} + +void KSim::Led::setOn(bool force) +{ + if (isOn() && !force) + return; + + // Return if our pixmap is null + QRect rect = d->splitter.coordinates(d->type == First ? 1 : 3); + if (d->pixmap.isNull() || rect.isEmpty()) { + resize(12, 8); + fill(Qt::white); + return; + } + + if (d->pixmap.mask() && !d->pixmap.mask()->isNull()) { + QBitmap mask(rect.size()); + bitBlt(&mask, QPoint(0, 0), d->pixmap.mask(), rect, CopyROP); + setMask(mask); + } + + bitBlt(this, QPoint(0, 0), &d->pixmap, rect, CopyROP); + d->toggled = true; +} + +void KSim::Led::setOff(bool force) +{ + if (!isOn() && !force) + return; + + // Return if our pixmap is null + QRect rect = d->splitter.coordinates(d->type == First ? 0 : 2); + if (d->pixmap.isNull() || rect.isEmpty()) { + resize(12, 8); + fill(Qt::white); + return; + } + + if (d->pixmap.mask() && !d->pixmap.mask()->isNull()) { + QBitmap mask(rect.size()); + bitBlt(&mask, QPoint(0, 0), d->pixmap.mask(), rect, CopyROP); + setMask(mask); + } + + bitBlt(this, QPoint(0, 0), &d->pixmap, rect, CopyROP); + d->toggled = false; +} + +void KSim::Led::toggle() +{ + if (d->toggled) + setOff(); + else + setOn(); +} + +void KSim::Led::setPixmap(const QString &imageName) +{ + if (imageName == d->imageName) + return; + + QImage image(imageName); + + if (image.width() >= 19) + image = image.smoothScale(19, image.height()); + + KSim::ThemeLoader::self().reColourImage(image); + d->pixmap.convertFromImage(image); + QSize size(image.width(), image.height() / 4); + + d->splitter.setPixmap(d->pixmap); + d->splitter.setItemSize(size); + + resize(size); + setMask(QBitmap()); +} + +const QString &KSim::Led::fileName() const +{ + return d->imageName; +} + +bool KSim::Led::isOn() const +{ + return d->toggled; +} + +void KSim::Led::setType(Type type) +{ + if (type == d->type) + return; + + d->type = type; +} + +KSim::Led::Type KSim::Led::type() const +{ + return d->type; +} + +void KSim::Led::update() +{ + if (isOn()) + setOn(true); + else + setOff(true); +} + +class KSim::LedLabel::Private +{ + public: + KSim::Led receiveLed; + KSim::Led sendLed; + QPoint sendPoint; + QPoint receivePoint; +}; + +KSim::LedLabel::LedLabel(int max, int type, const QString &label, + QWidget *parent, const char *name, WFlags fl) + : KSim::Progress(max, type, Panel, parent, name, fl) +{ + init(); + setText(label); +} + +KSim::LedLabel::LedLabel(int max, int type, + QWidget *parent, const char *name, WFlags fl) + : KSim::Progress(max, type, Panel, parent, name, fl) +{ + init(); +} + +KSim::LedLabel::LedLabel(int max, + QWidget *parent, const char *name, WFlags fl) + : KSim::Progress(max, KSim::Types::None, + Panel, parent, name, fl) +{ + init(); +} + +KSim::LedLabel::~LedLabel() +{ + delete d; +} + +void KSim::LedLabel::configureObject(bool reapaintWidget) +{ + KSim::Progress::configureObject(false); + + QPixmap pixmap = themeLoader().current().splitPixmap(KSim::Theme::KrellPanel, 0, false); + if (pixmap.isNull()) + pixmap = themeLoader().current().splitPixmap(KSim::Theme::KrellSlider); + + setMeterPixmap(pixmap); + d->receiveLed.setPixmap(themeLoader().current().ledPixmap(KSim::Types::Net)); + d->sendLed.setPixmap(themeLoader().current().ledPixmap(KSim::Types::Net)); + + // Update the leds to make sure they get painted correctly + d->receiveLed.update(); + d->sendLed.update(); + + setConfigValues(); + layoutLeds(); + + if (reapaintWidget) + update(); +} + +QSize KSim::LedLabel::sizeHint() const +{ + QSize hint(Progress::sizeHint()); + + if (d->sendLed.height() > hint.height()) + hint.setHeight(d->sendLed.height()); + + return hint; +} + +void KSim::LedLabel::reset() +{ + KSim::Progress::reset(); + setOff(Led::First); + setOff(Led::Second); +} + +void KSim::LedLabel::setOn(Led::Type type) +{ + if (type == Led::First) { + if (d->receiveLed.isOn()) + return; + + d->receiveLed.setOn(); + } + else { + if (d->sendLed.isOn()) + return; + + d->sendLed.setOn(); + } + + update(); +} + +void KSim::LedLabel::setOff(Led::Type type) +{ + if (type == Led::First) { + if (!d->receiveLed.isOn()) + return; + + d->receiveLed.setOff(); + } + else { + if (!d->sendLed.isOn()) + return; + + d->sendLed.setOff(); + } + + update(); +} + +void KSim::LedLabel::toggle(Led::Type type) +{ + if (type == Led::First) + d->receiveLed.toggle(); + else + d->sendLed.toggle(); + + update(); +} + +void KSim::LedLabel::drawLeds() +{ + bitBlt(this, d->sendPoint, &d->sendLed); + bitBlt(this, d->receivePoint, &d->receiveLed); +} + +void KSim::LedLabel::paintEvent(QPaintEvent *ev) +{ + KSim::Label::paintEvent(ev); + drawLeds(); + KSim::Progress::drawMeter(); +} + +void KSim::LedLabel::resizeEvent(QResizeEvent *ev) +{ + KSim::Progress::resizeEvent(ev); + layoutLeds(); +} + +void KSim::LedLabel::layoutLeds() +{ + int ledHeight = height() / 2; + + // get the location of the sendLed + d->sendPoint.setX((width() - d->sendLed.width()) - 2); + d->sendPoint.setY(ledHeight - (d->sendLed.height() / 2)); + + // get the location of the receiveLed + d->receivePoint.setX((d->sendPoint.x() - d->receiveLed.width()) - 3); + d->receivePoint.setY(ledHeight - (d->receiveLed.height() / 2)); + + QRect location = textLocation(); + location.setWidth(d->receivePoint.x()); + setTextLocation(location); + + QRect shadow = shadowLocation(); + shadow.setWidth(d->receivePoint.x() + 3); + setShadowLocation(shadow); + + setOrigin(rect()); +} + +void KSim::LedLabel::init() +{ + d = new Private; + d->receiveLed.setType(KSim::Led::First); + d->sendLed.setType(KSim::Led::Second); + setConfigString("StylePanel"); + configureObject(); +} diff --git a/ksim/library/led.h b/ksim/library/led.h new file mode 100644 index 0000000..2e5d084 --- /dev/null +++ b/ksim/library/led.h @@ -0,0 +1,193 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#ifndef KSIM__LED_H +#define KSIM__LED_H + +#include "progress.h" +#include <kdemacros.h> +#include <qpixmap.h> + +namespace KSim +{ + /** + * A custom led for use with KSim::LedLabel, + * usually you shouldn't need to use this class, use KSim::LedLabel instead + * @see KSim::LedLabel + * + * @short led using gkrellm themes + * @author Robbie Ward <linuxphreak@gmx.co.uk> + */ + class KDE_EXPORT Led : public QPixmap + { + public: + enum Type { First = 0, Second }; + Led(); + /** + * Constructs a KSim::Led. + * + * @param type is the led type + * @param ImageName is the image to display + * the image's height is divided by 4 and each item is used for send in, + * send out, receive in and receive out + * @param parent is the parent widget + * @param name is the object instance name + */ + Led(Type type, const QString &imageName); + /** + * destructor for KSim::Led. + */ + virtual ~Led(); + + /** + * sets the led on + */ + void setOn(bool force = false); + /** + * sets the led off + */ + void setOff(bool force = false); + /** + * toggles the current state of the led + */ + void toggle(); + /** + * sets the image of the led + */ + void setPixmap(const QString &); + /** + * @return the location of the filename + */ + const QString &fileName() const; + /** + * @return true if the led is on + */ + bool isOn() const; + /** + * sets the type of led, send or receive + */ + void setType(Type type); + /** + * @return the type of the led + */ + Type type() const; + /** + * Force the Led to repaint its state + */ + void update(); + + private: + class Private; + Private *d; + }; + + /** + * A custom widget that inheriits KSim::Progress. + * this wiget provides two KSim::Led's and a label + * + * @short Label widget with 2 leds + * @author Robbie Ward <linuxphreak@gmx.co.uk> + */ + class KDE_EXPORT LedLabel : public KSim::Progress + { + Q_OBJECT + public: + /** + * Constructs a KSim::LedLabel. + * + * @param type is the theme type + * @param label is the default text to display + * @param parent is the parent widget + * @see KSim::ThemeLoader + */ + LedLabel(int max, int type, const QString &label, + QWidget *parent, const char *name = 0, WFlags fl = 0); + /** + * Constructs a KSim::LedLabel. + * + * @param type is the theme type + * @param label is the default text to display + * @param parent is the parent widget + * @see KSim::ThemeLoader + */ + LedLabel(int max, int type, QWidget *parent, + const char *name = 0, WFlags fl = 0); + /** + * Constructs a KSim::LedLabel. + * + * @param label is the default text to display + * @param parent is the parent widget + * @see KSim::ThemeLoader + */ + LedLabel(int max, QWidget *parent, + const char *name = 0, WFlags fl = 0); + /** + * destructor for KSim::LedLabel. + */ + virtual ~LedLabel(); + + /** + * reimplemented for internal reasons + */ + virtual void configureObject(bool reapaintWidget = true); + /** + * reimplemented for internal reasons + */ + virtual QSize sizeHint() const; + + public slots: + /** + * reimplemented for internal reasons + */ + virtual void reset(); + /** + * sets @ref ledType on + */ + void setOn(Led::Type type); + /** + * sets @ref ledType off + */ + void setOff(Led::Type type); + /** + * toggles the state of @ref ledType + * if the led is on then it will be set off, + * if the led is off it will be set on. + */ + void toggle(Led::Type type); + + protected: + void drawLeds(); + /** + * reimplemented for internal reasons + */ + virtual void paintEvent(QPaintEvent *); + /** + * reimplemented for internal reasons + */ + virtual void resizeEvent(QResizeEvent *); + + private: + void layoutLeds(); + void init(); + + class Private; + Private *d; + }; +} +#endif // KSIMLED_H diff --git a/ksim/library/pluginglobal.cpp b/ksim/library/pluginglobal.cpp new file mode 100644 index 0000000..02b32ad --- /dev/null +++ b/ksim/library/pluginglobal.cpp @@ -0,0 +1,207 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#include "pluginglobal.h" +#include "pluginmodule.h" + +#include <kdebug.h> +#include <kdesktopfile.h> +#include <klocale.h> +#include <kiconloader.h> + +class KSim::Plugin::Private +{ + public: + Private() : plugin(0), + view(0), page(0) + { + oldState = true; + enabled = true; + // Set the ref-count to 1 + count = 1; + } + + ~Private() + { + kdDebug(2003) << "Deleting " << (plugin ? + plugin->name() : QString("Null")) + << " objects." << endl; + + // Remember to delete the objects we own + delete plugin; + delete view; + delete page; + + plugin = 0; + view = 0; + page = 0; + } + + void ref() { ++count; } + bool deref() { return !--count; } + + uint count; + QString name; + QPixmap icon; + QCString libName; + QString filename; + KSim::PluginObject *plugin; + KSim::PluginView *view; + KSim::PluginPage *page; + bool oldState; + bool enabled; +}; + +KSim::Plugin KSim::Plugin::null; + +// Null Plugin +KSim::Plugin::Plugin() : d(0) +{ +} + +KSim::Plugin::Plugin(KSim::PluginObject *plugin, const KDesktopFile &file) +{ + init(plugin, file); + + if (d) { + d->view = d->plugin ? d->plugin->createView(d->libName) : 0; + d->page = d->plugin ? d->plugin->createConfigPage(d->libName) : 0; + } +} + +KSim::Plugin::Plugin(const KSim::Plugin &rhs) +{ + d = rhs.d; + if (d) + d->ref(); +} + +KSim::Plugin::~Plugin() +{ + if (d && d->deref()) + delete d; +} + +KSim::Plugin &KSim::Plugin::operator=(const KSim::Plugin &rhs) +{ + if (*this == rhs) + return *this; + + if (rhs.d) { + rhs.d->ref(); + if (d && d->deref()) + delete d; + + d = rhs.d; + return *this; + } + + // rhs is a null plugin so we just go ahead + // and make this a null plugin too. + if (d && d->deref()) + delete d; + + d = 0; + return *this; +} + +bool KSim::Plugin::operator==(const KSim::Plugin &rhs) const +{ + return d == rhs.d; +} + +bool KSim::Plugin::operator!=(const KSim::Plugin &rhs) const +{ + return !(operator==(rhs)); +} + +void KSim::Plugin::setEnabled(bool enabled) +{ + if (!d) + return; + + d->oldState = d->enabled; + d->enabled = enabled; +} + +bool KSim::Plugin::isEnabled() const +{ + return (d ? d->enabled : false); +} + +bool KSim::Plugin::isDifferent() const +{ + return d ? d->enabled != d->oldState : false; +} + +bool KSim::Plugin::isNull() const +{ + return !d; +} + +const QString &KSim::Plugin::name() const +{ + return d ? d->name : QString::null; +} + +QPixmap KSim::Plugin::icon() const +{ + return d ? d->icon : QPixmap(); +} + +QCString KSim::Plugin::libName() const +{ + return d ? d->libName : QCString(); +} + +const QString &KSim::Plugin::fileName() const +{ + return d ? d->filename : QString::null; +} + +KSim::PluginObject *KSim::Plugin::plugin() const +{ + return d ? d->plugin : 0; +} + +KSim::PluginView *KSim::Plugin::view() const +{ + return d ? d->view : 0; +} + +KSim::PluginPage *KSim::Plugin::configPage() const +{ + return d ? d->page : 0; +} + +void KSim::Plugin::init(KSim::PluginObject *plugin, const KDesktopFile &file) +{ + if (!plugin || file.fileName().isEmpty()) { + d = 0; + return; + } + + d = new Private; + + d->libName = "ksim_" + file.readEntry("X-KSIM-LIBRARY").local8Bit(); + d->name = file.readName(); + d->icon = SmallIcon(file.readIcon()); + d->filename = file.fileName(); + d->plugin = plugin; +} diff --git a/ksim/library/pluginglobal.h b/ksim/library/pluginglobal.h new file mode 100644 index 0000000..85df9ce --- /dev/null +++ b/ksim/library/pluginglobal.h @@ -0,0 +1,161 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#ifndef PLUGINGLOBAL_H +#define PLUGINGLOBAL_H + +#include <qstring.h> +#include <qpixmap.h> +#include <qvaluelist.h> + +#include <kdemacros.h> + +class KDesktopFile; + +namespace KSim +{ + class PluginObject; + class PluginView; + class PluginPage; + + /** + * A class that holds various information about a plugin + * @author Robbie Ward <linuxphreak@gmx.co.uk> + */ + class KDE_EXPORT Plugin + { + public: + /** + * Constructs a null Plugin + */ + Plugin(); + /** + * Constructs a Plugin + */ + Plugin(KSim::PluginObject *plugin, const KDesktopFile &file); + /** + * Copy constructor + */ + Plugin(const Plugin &rhs); + /** + * Destructor for Plugin + */ + ~Plugin(); + + /** + * Assigns rhs to this Plugin and returns a reference to this Plugin. + */ + Plugin &operator=(const Plugin &rhs); + /** + * @return true if the plugin is equal to rhs; otherwise returns false + * @see #operator!= + */ + bool operator==(const Plugin &rhs) const; + /** + * @return true if the plugin is different to rhs; otherwise returns false + * @see #operator== + */ + bool operator!=(const Plugin &rhs) const; + /** + * sets if the plugin is enabled or not + */ + void setEnabled(bool enabled); + /** + * returns true if this plugin is enabled, else it returns false + */ + bool isEnabled() const; + /** + * returns true if the last enabled state is different to the current + * enabled state, else it returns false + */ + bool isDifferent() const; + /** + * @return true if the Plugin object is empty + */ + bool isNull() const; + /** + * @return the name of the plugin, NOT the library name + * @see #libName + */ + const QString &name() const; + /** + * @return the icon of the plugin + */ + QPixmap icon() const; + /** + * @return library name of the plugin + */ + QCString libName() const; + /** + * @return path to the .desktop file + */ + const QString &fileName() const; + /** + * @return the plugin object + */ + KSim::PluginObject *plugin() const; + /** + * @return the view object of the plugin + */ + KSim::PluginView *view() const; + /** + * @return the config object of the plugin + */ + KSim::PluginPage *configPage() const; + /** + * a null plugin, provided for convenience. + * currently only used in KSim::PluginLoader + */ + static KSim::Plugin null; + private: + void init(KSim::PluginObject *plugin, const KDesktopFile &file); + + class Private; + Private *d; + }; + + /** + * Please do not use this class directly, + * use pluginList() from KSim::PluginLoader instead + * @author Robbie Ward <linuxphreak@gmx.co.uk> + */ + class KDE_EXPORT PluginList : public QValueList<Plugin> + { + public: + /** + * constructs a null list + */ + PluginList() : QValueList<Plugin>() {} + /** + * constructs a copy of @p list + */ + PluginList(const PluginList &list) : QValueList<Plugin>(list) {} + /** + * constructs a copy of @p list + */ + PluginList(const QValueList<Plugin> &list) + : QValueList<Plugin>(list) {} + /** + * constructs a list with just one item + */ + PluginList(const Plugin &plugin) { append(plugin); } + ~PluginList() {} + }; +} +#endif diff --git a/ksim/library/pluginloader.cpp b/ksim/library/pluginloader.cpp new file mode 100644 index 0000000..be2d2bf --- /dev/null +++ b/ksim/library/pluginloader.cpp @@ -0,0 +1,326 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#include "pluginloader.h" +#include "pluginloader.moc" + +#include <kdebug.h> +#include <klibloader.h> +#include <kdesktopfile.h> +#include <klocale.h> +#include <kglobal.h> +#include <kstandarddirs.h> +#include <kmessagebox.h> + +#include <qstringlist.h> + +class KSim::PluginInfo::Private +{ + public: +}; + +KSim::PluginInfo::~PluginInfo() +{ +} + +const QString &KSim::PluginInfo::name() const +{ + return m_name; +} + +QCString KSim::PluginInfo::libName(bool includePrefix) const +{ + return (includePrefix ? "ksim_" + m_libName : m_libName); +} + +const QString &KSim::PluginInfo::location() const +{ + return m_location; +} + +KSim::PluginInfo::PluginInfo() +{ +} + +class KSim::PluginLoader::Private +{ + public: + typedef KSim::PluginObject *(PluginPtr)(const char *); + KSim::PluginList pluginList; + QString error; + QString lib; + bool lastLoaded; + static const char *const ksimString; +}; + +const char *const KSim::PluginLoader::Private::ksimString = "ksim_"; + +KSim::PluginLoader *KSim::PluginLoader::m_instance = 0; // initialize pointer +KSim::PluginLoader &KSim::PluginLoader::self() +{ + if (!m_instance) // is it the first call? + m_instance = new PluginLoader; // create sole instance + + return *m_instance; // address of sole instance +} + +KSim::PluginLoader::~PluginLoader() +{ + unloadAllPlugins(); + delete d; +} + +bool KSim::PluginLoader::loadPlugin(const KDesktopFile &file) +{ + switch (createPlugin(file)) { + case KSim::PluginLoader::EmptyLibName: + KMessageBox::error(0, i18n("KSim was unable to load the plugin %1" + " due to the X-KSIM-LIBRARY property being empty in the" + " plugins desktop file").arg(file.readName())); + return false; + break; + case KSim::PluginLoader::LibNotFound: + KMessageBox::error(0, i18n("KSim was unable to load the plugin %1" + " due to not being able to find the plugin, check that the plugin" + " is installed and is in your $KDEDIR/lib path").arg(file.readName())); + return false; + break; + case KSim::PluginLoader::UnSymbols: + KMessageBox::error(0, i18n("<qt>An error occurred while trying \n" + "to load the plugin '%1'. \nThis could be caused by the" + " following:<ul>\n<li>The plugin doesn't have the %2" + " macro</li>\n<li>The plugin has been damaged or has" + " some unresolved symbols</li>\n</ul> \nLast" + " error message that occurred: \n%3</qt>") + .arg(d->lib.prepend("ksim_")).arg("KSIM_INIT_PLUGIN") + .arg(d->error)); + return false; + break; + default: + break; + } + + return true; +} + +bool KSim::PluginLoader::unloadPlugin(const QCString &name) +{ + if (name.isEmpty()) + return false; + + // see if our plugin is loaded + KSim::Plugin plugin = find(name); + if (plugin.isNull()) + return false; + + // try to unload the library + kdDebug(2003) << "Unloading plugin " << plugin.libName() << endl; + KLibLoader::self()->unloadLibrary(plugin.libName()); + d->pluginList.remove(plugin); + return true; +} + +void KSim::PluginLoader::unloadAllPlugins() +{ + kdDebug(2003) << "Unloading all plugins" << endl; + + // Go through the plugin list and unload each plugin; + KSim::PluginList::ConstIterator it; + for (it = d->pluginList.begin(); it != d->pluginList.end(); ++it) { + KLibLoader::self()->unloadLibrary((*it).libName()); + } + + // Clear the plugin list; + d->pluginList.clear(); + KLibLoader::cleanUp(); +} + +bool KSim::PluginLoader::isLoaded(const KSim::Plugin &info) const +{ + return isLoaded(info.libName()); +} + +bool KSim::PluginLoader::isLoaded(const QCString &library) const +{ + if (library.isEmpty()) + return false; + + return !find(library).isNull(); +} + +KSim::PluginInfo KSim::PluginLoader::findPluginInfo(const QString &name, + SearchType type) const +{ + QString location; + + switch (type) { + case Name: { + QStringList files = KGlobal::dirs()->findAllResources("data", "ksim/monitors/*.desktop"); + QStringList::ConstIterator it; + for (it = files.begin(); it != files.end(); ++it) { + KDesktopFile file((*it)); + if (file.readName() == name) { + location = (*it); + break; + } + } + break; + } + case LibName: { + QStringList files = KGlobal::dirs()->findAllResources("data", "ksim/monitors/*.desktop"); + QStringList::ConstIterator it; + for (it = files.begin(); it != files.end(); ++it) { + KDesktopFile file((*it)); + if (file.readEntry("X-KSIM-LIBRARY") == name) { + location = (*it); + break; + } + } + break; + } + case DesktopFile: { + if (!KDesktopFile::isDesktopFile(name)) + return KSim::PluginInfo(); + + location = name; + break; + } + } + + KDesktopFile file(location); + KSim::PluginInfo info; + info.m_name = file.readName(); + info.m_libName = file.readEntry("X-KSIM-LIBRARY").local8Bit(); + info.m_location = location; + return info; +} + +KSim::Plugin &KSim::PluginLoader::find(const QCString &libName) +{ + if (libName.isEmpty()) + return KSim::Plugin::null; + + QCString library(libName); + if (libName.find(Private::ksimString) == -1) + library.prepend(Private::ksimString); + + KSim::PluginList::Iterator it; + for (it = d->pluginList.begin(); it != d->pluginList.end(); ++it) { + if ((*it).libName() == library) + return (*it); + } + + return KSim::Plugin::null; +} + +const KSim::Plugin &KSim::PluginLoader::find(const QCString &libName) const +{ + if (libName.isEmpty()) + return KSim::Plugin::null; + + QCString library(libName); + if (libName.find(Private::ksimString) == -1) + library.prepend(Private::ksimString); + + KSim::PluginList::ConstIterator it; + for (it = d->pluginList.begin(); it != d->pluginList.end(); ++it) { + if ((*it).libName() == library) + return (*it); + } + + return KSim::Plugin::null; +} + +KSim::Plugin &KSim::PluginLoader::find(const KSim::PluginInfo &info) +{ + return find(info.libName()); +} + +const KSim::Plugin &KSim::PluginLoader::find(const KSim::PluginInfo &info) const +{ + return find(info.libName()); +} + +const KSim::PluginList &KSim::PluginLoader::pluginList() const +{ + return d->pluginList; +} + +KSim::PluginList &KSim::PluginLoader::pluginList() +{ + return d->pluginList; +} + +const KSim::Plugin &KSim::PluginLoader::plugin() const +{ + return (d->lastLoaded ? d->pluginList.last() : KSim::Plugin::null); +} + +KSim::Plugin &KSim::PluginLoader::plugin() +{ + return (d->lastLoaded ? d->pluginList.last() : KSim::Plugin::null); +} + +KSim::PluginLoader::PluginLoader() : QObject(0, "PluginLoader") +{ + d = new KSim::PluginLoader::Private; + d->lastLoaded = false; +} + +void KSim::PluginLoader::cleanup() +{ + if (!m_instance) + return; + + delete m_instance; + m_instance = 0; +} + +KSim::PluginLoader::ErrorCode KSim::PluginLoader::createPlugin(const KDesktopFile &file) +{ + d->error = QString::null; + QCString pluginName(file.readEntry("X-KSIM-LIBRARY").local8Bit()); + if (pluginName.isEmpty()) + return EmptyLibName; + + QCString libName(Private::ksimString + pluginName); + KLibrary *library = KLibLoader::self()->library(libName); + if (!library) + return LibNotFound; + + QCString symbol("init_plugin"); + if (Private::PluginPtr *create = (Private::PluginPtr *)(library->symbol(symbol))) { + d->pluginList.append(KSim::Plugin(create(pluginName), file)); + d->lib = QString::null; + d->lastLoaded = true; + } + else { + d->error = KLibLoader::self()->lastErrorMessage().isEmpty() ? + i18n("Unable to get last error message") : + KLibLoader::self()->lastErrorMessage(); + + KLibLoader::self()->unloadLibrary(libName); + d->lib = pluginName; + d->lastLoaded = false; + return UnSymbols; + } + + emit pluginLoaded(d->pluginList.last()); + return LibLoaded; +} diff --git a/ksim/library/pluginloader.h b/ksim/library/pluginloader.h new file mode 100644 index 0000000..f101973 --- /dev/null +++ b/ksim/library/pluginloader.h @@ -0,0 +1,183 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#ifndef PLUGINLOADER_H +#define PLUGINLOADER_H + +#include "pluginglobal.h" +#include <qobject.h> + +#include <kdemacros.h> + +namespace KSim +{ + class KDE_EXPORT PluginInfo + { + friend class PluginLoader; + public: + ~PluginInfo(); + + /** + * @return the name of the plugin + */ + const QString &name() const; + /** + * @return the library name of the plugin + */ + QCString libName(bool includePrefix = false) const; + /** + * @return the location of the desktop file + */ + const QString &location() const; + + private: + PluginInfo(); + + QString m_name; + QString m_location; + QCString m_libName; + + class Private; + Private *d; + }; + + /** + * Provides a loader for the plugins + * @author Robbie Ward <linuxphreak@gmx.co.uk> + */ + class KDE_EXPORT PluginLoader : public QObject + { + Q_OBJECT + friend class MainView; + public: + enum SearchType { Name = 0, DesktopFile, LibName }; + enum ErrorCode { EmptyLibName = -3, LibNotFound = -2, + UnSymbols = -1, LibLoaded = 0 }; + + /** + * @return a reference to the instance + */ + static PluginLoader &self(); + /** + * loads a plugin, example: + * <pre> + * KDesktopFile deskfile("/home/user/foo.desktop"); + * KSim::PluginLoader::self().loadPlugin(deskFile); + * </pre> + * you can then use @ref pluginList() to access the plugin, view, + * config page and plugin information + * @param file is the desktop file of the lib + * @return true if the plugin is successfully loaded + */ + bool loadPlugin(const KDesktopFile &file); + /** + * unloads a loaded plugin and removes plugin entries from pluginList() + */ + bool unloadPlugin(const QCString &name); + /** + * unloads all loaded plugins + */ + void unloadAllPlugins(); + /** + * convenience function + * + * returns true if info is loaded + */ + bool isLoaded(const KSim::Plugin &info) const; + /** + * returns true if library is loaded + */ + bool isLoaded(const QCString &library) const; + /** + * finds the plugins desktopfile and returns information + * on the plugin + * @return a KSim::PluginInfo object + * @see KSim::PluginInfo + */ + KSim::PluginInfo findPluginInfo(const QString &name, + SearchType type = DesktopFile) const; + /** + * looks through the list of loaded plugins and returns + * the one that matches libName, or returns + * KSim::Plugin::null if a plugin could not be found. + * + * if libName does not start with "ksim_" then the function + * will prepend this automatically. + * @return a KSim::Plugin object + * @see KSim::Plugin + */ + KSim::Plugin &find(const QCString &libName); + /** + * convenience function, see the above function for details. + */ + const KSim::Plugin &find(const QCString &libName) const; + /** + * equivalent to find(info.libName()); + */ + KSim::Plugin &find(const KSim::PluginInfo &info); + /** + * convenience function, see the above function for details. + */ + const KSim::Plugin &find(const KSim::PluginInfo &info) const; + /** + * provides plugin(), view(), config page and plugin information + * @see KSim::Plugin KSim::PluginList + */ + const KSim::PluginList &pluginList() const; + /** + * Overloaded member function, This behaves essentially like + * the above function + */ + KSim::PluginList &pluginList(); + /** + * @return a reference to the last plugin loaded (or a null plugin + * if the plugin was unable to load) + */ + const KSim::Plugin &plugin() const; + /** + * Overloaded member function, This behaves essentially like + * the above function + */ + KSim::Plugin &plugin(); + + signals: + void pluginLoaded(const KSim::Plugin &); + + protected: + /** + * constructor for PluginLoader, use self() to get an instance + */ + PluginLoader(); + ~PluginLoader(); + + private: + PluginLoader(const PluginLoader &); + PluginLoader &operator=(const PluginLoader &); + /** + * Deletes the instance and cleans up after itself + */ + static void cleanup(); + ErrorCode createPlugin(const KDesktopFile &file); + + class Private; + Private *d; + static PluginLoader *m_instance; + }; +} +#endif diff --git a/ksim/library/pluginmodule.cpp b/ksim/library/pluginmodule.cpp new file mode 100644 index 0000000..f267197 --- /dev/null +++ b/ksim/library/pluginmodule.cpp @@ -0,0 +1,174 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#include "pluginmodule.h" +#include "pluginmodule.moc" + +#include <klocale.h> +#include <kapplication.h> +#include <kaboutdata.h> +#include <kdebug.h> +#include <qregexp.h> +#include <qpopupmenu.h> +#include <kconfig.h> + + +class KSim::PluginObject::Private +{ + public: + QCString name; + QString configName; +}; + +KSim::PluginObject::PluginObject(const QCString &name) +{ + d = new PluginObject::Private; + d->name = name; + d->configName = "ksim_" + name; +} + +KSim::PluginObject::~PluginObject() +{ + delete d; +} + +const char *KSim::PluginObject::instanceName() const +{ + return kapp->aboutData()->appName(); +} + +const QCString &KSim::PluginObject::name() const +{ + return d->name; +} + +void KSim::PluginObject::setConfigFileName(const QString &name) +{ + if (d->configName == name) + return; + + d->configName = name; + if (name.find("ksim") == -1) + d->configName.prepend("ksim_"); +} + +const QString &KSim::PluginObject::configFileName() const +{ + return d->configName; +} + +class KSim::PluginPage::Private +{ + public: + KConfig *config; + KSim::PluginObject *parent; +}; + +KSim::PluginPage::PluginPage(KSim::PluginObject *parent, const char *name) + : QWidget(0, name) +{ + d = new PluginPage::Private; + d->parent = parent; + if (parent && !parent->configFileName().isEmpty()) + d->config = new KConfig(parent->configFileName() + "rc"); + else { + kdWarning() << className() << ": Can not create the config() " + "pointer due to the parent being null" << endl; + d->config = 0; + } +} + +KSim::PluginPage::~PluginPage() +{ + delete d->config; + delete d; +} + +KConfig *KSim::PluginPage::config() const +{ + if (d) + return d->config; + else + return 0; +} + +class KSim::PluginView::Private +{ + public: + PluginObject *parent; + QPopupMenu *popupMenu; + KConfig *config; +}; + +KSim::PluginView::PluginView(KSim::PluginObject *parent, const char *name) + : QWidget(0, name) +{ + d = new PluginView::Private; + d->parent = parent; + d->popupMenu = new QPopupMenu(this); + d->popupMenu->insertItem(i18n("About"), this, + SLOT(showAbout()), 0, -1, 0); + + if (parent && !parent->configFileName().isEmpty()) + d->config = new KConfig(parent->configFileName() + "rc"); + else { + kdWarning() << className() << ": Can not create the config() " + "pointer due to the parent being null" << endl; + d->config = 0; + } +} + +KSim::PluginView::~PluginView() +{ + delete d->popupMenu; + delete d->config; + delete d; + d = 0; +} + +KConfig *KSim::PluginView::config() const +{ + return d->config; +} + +QPopupMenu *KSim::PluginView::menu() const +{ + return d->popupMenu; +} + +void KSim::PluginView::doCommand() +{ + emit runCommand(name()); +} + +void KSim::PluginView::mousePressEvent(QMouseEvent *ev) +{ + if (ev->button() == QMouseEvent::LeftButton) + doCommand(); +} + +KSim::PluginObject *KSim::PluginView::parentPlugin() const +{ + return d->parent; +} + +void KSim::PluginView::showAbout() +{ + parentPlugin()->showAbout(); +} diff --git a/ksim/library/pluginmodule.h b/ksim/library/pluginmodule.h new file mode 100644 index 0000000..1cc6a1c --- /dev/null +++ b/ksim/library/pluginmodule.h @@ -0,0 +1,205 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#ifndef PLUGINMODULE_H +#define PLUGINMODULE_H + +#include <qwidget.h> + +#include <kdemacros.h> + +class QPopupMenu; +class KConfig; + +#define KSIM_INIT_PLUGIN(className) \ +extern "C" { \ + KDE_EXPORT KSim::PluginObject *init_plugin(const char *name) { \ + return new className(name); \ + } \ +} + +namespace KSim +{ + class PluginView; + class PluginPage; + + /** + * The base class for ksim modules. + * + * To init a plugin so KSim can load your plugin just do: + * <pre> + * // MyPluginModule is the class that inherits KSim::PluginObject + * KSIM_INIT_PLUGIN(MyPluginModule); + * </pre> + * @see KSim::PluginView KSim::PluginPage + * @author Robbie Ward <linuxphreak@gmx.co.uk> + */ + class KDE_EXPORT PluginObject + { + public: + /** + * constructor for PluginObject + */ + PluginObject(const QCString &name); + /** + * destructor for PluginObject + */ + virtual ~PluginObject(); + + /** + * creates a new View page, re-implement this + * to return your main view class + */ + virtual KSim::PluginView *createView(const char *) = 0; + /** + * creates a new Config page, re-implement this + * to return you config class + */ + virtual KSim::PluginPage *createConfigPage(const char *) = 0; + /** + * re-implement this to show your about dialog + */ + virtual void showAbout() = 0; + /** + * @return the instance name of the app + */ + const char *instanceName() const; + /** + * @return the name of the plugin + */ + const QCString &name() const; + /** + * sets the configuration file name to @p name + */ + void setConfigFileName(const QString &name); + /** + * @return the config filename the plugin should use + * or name() if the filename hasn't been set + */ + const QString &configFileName() const; + + private: + PluginObject(); + PluginObject(const PluginObject &); + PluginObject &operator=(const PluginObject &); + + class Private; + Private *d; + }; + + /** + * Provides you with a config page + * + * re-implement readConfig() and saveConfig() for your + * classes reading and saving functions and use + * the config() to gain access to your config file + * @author Robbie Ward <linuxphreak@gmx.co.uk> + */ + class KDE_EXPORT PluginPage : public QWidget + { + Q_OBJECT + public: + /** + * constructor for PluginPage + */ + PluginPage(KSim::PluginObject *parent, const char *name); + /** + * destructor for PluginPage + */ + virtual ~PluginPage(); + + /** + * called when apply or ok button is clicked in KSimPref + * use this to save your plugin options + */ + virtual void saveConfig() = 0; + /** + * called when apply or ok button is clicked in KSimPref + * use this to read your plugin options + */ + virtual void readConfig() = 0; + /* + * use this to get a config object unique to the plugin name, + * eg: the plugin foo would have the config file foorc + */ + KConfig *config() const; + + signals: + void pageChanged(); + + protected: + PluginObject *parentPlugin() const; + + private: + class Private; + Private *d; + }; + + /** + * inherit from this class to get your base view + * + * use config() to get an instance of your config file, + * reimplement reparseConfig() to recreate your view + * when apply or ok gets clicked in the config dialog + * @author Robbie Ward <linuxphreak@gmx.co.uk> + */ + class KDE_EXPORT PluginView : public QWidget + { + Q_OBJECT + public: + /** + * constructor for PluginView + */ + PluginView(KSim::PluginObject *parent, const char *name); + /** + * destructor for PluginView + */ + virtual ~PluginView(); + + /* + * use this to get a config object unique to the plugin name, + * eg: the plugin foo would have the config file foorc + */ + KConfig *config() const; + /** + * the plugins popup menu + */ + QPopupMenu *menu() const; + /** + * reimplement to recreate your view when KSim requests this + */ + virtual void reparseConfig() = 0; + void doCommand(); + + signals: + void runCommand(const QCString &); + + protected: + virtual void mousePressEvent(QMouseEvent *); + PluginObject *parentPlugin() const; + + private slots: + void showAbout(); + + private: + class Private; + Private *d; + }; +} +#endif diff --git a/ksim/library/progress.cpp b/ksim/library/progress.cpp new file mode 100644 index 0000000..fd923d2 --- /dev/null +++ b/ksim/library/progress.cpp @@ -0,0 +1,231 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#include "progress.h" +#include "progress.moc" + +#include <kdebug.h> +#include <qpainter.h> +#include <qpixmap.h> +#include <qimage.h> + +#include <themeloader.h> + +class KSim::Progress::Private +{ + public: + QPixmap meterPixmap; + QRect rectOrigin; + ProgressType type; + int krellDepth; + int value; + int minValue; + int maxValue; +}; + +KSim::Progress::Progress(int maxValue, + QWidget *parent, const char *name, + WFlags fl) : KSim::Label(parent, name, fl) +{ + init(maxValue); + configureObject(); +} + +KSim::Progress::Progress(int maxValue, + int type, const QString &label, QWidget *parent, + const char *name, WFlags fl) + : KSim::Label(type, label, parent, name, fl) +{ + init(maxValue); + configureObject(); +} + +KSim::Progress::Progress(int maxValue, + int type, const QString &label, int value, + QWidget *parent, const char *name, WFlags fl) + : KSim::Label(type, label, parent, name, fl) +{ + init(maxValue, value); + configureObject(); +} + +KSim::Progress::Progress(int maxValue, + int type, QWidget *parent, + const char *name, WFlags fl) + : KSim::Label(type, parent, name, fl) +{ + init(maxValue); + configureObject(); +} + +KSim::Progress::Progress(int maxValue, int type, + ProgressType progressType, + QWidget *parent, const char *name, WFlags fl) + : KSim::Label(type, parent, name, fl) +{ + init(maxValue, 0, progressType); + configureObject(); +} + +KSim::Progress::~Progress() +{ + delete d; +} + +int KSim::Progress::value() const +{ + return d->value; +} + +int KSim::Progress::minValue() const +{ + return d->minValue; +} + +int KSim::Progress::maxValue() const +{ + return d->maxValue; +} + +const QRect &KSim::Progress::rectOrigin() const +{ + return d->rectOrigin; +} + +void KSim::Progress::configureObject(bool repaintWidget) +{ + KSim::Label::configureObject(false); + + if (d->type == Panel) { + setMeterPixmap(themeLoader().current().splitPixmap(KSim::Theme::KrellPanel)); + setThemePixmap(themeLoader().current().panelPixmap(type())); + } + else { + setMeterPixmap(themeLoader().current().splitPixmap(KSim::Theme::KrellMeter)); + } + + if (repaintWidget) + update(); +} + +QSize KSim::Progress::sizeHint() const +{ + QSize hint(Label::sizeHint()); + + if (d->meterPixmap.height() > hint.height()) + hint.setHeight(d->meterPixmap.height()); + + return hint; +} + +void KSim::Progress::reset() +{ + KSim::Label::clear(); + setMinValue(0); + setMaxValue(0); + setValue(0); +} + +void KSim::Progress::setValue(int value) +{ + if (value == d->value) + return; + + d->value = value; + if (value < minValue()) + d->value = minValue(); + + if (value > maxValue()) + d->value = maxValue(); + + update(); +} + +void KSim::Progress::setMinValue(int minValue) +{ + if (d->minValue == minValue) + return; + + if (!(minValue > maxValue())) { + d->minValue = minValue; + update(); + } +} + +void KSim::Progress::setMaxValue(int maxValue) +{ + if (d->maxValue == maxValue) + return; + + if (!(maxValue < minValue())) { + d->maxValue = maxValue; + update(); + } +} + +void KSim::Progress::setOrigin(const QRect &origin) +{ + d->rectOrigin = origin; +} + +void KSim::Progress::setMeterPixmap(const QPixmap &pixmap) +{ + QSize oldSize = sizeHint(); + d->meterPixmap = pixmap; + relayoutLabel(oldSize); +} + +int KSim::Progress::xLocation() const +{ + int position = d->rectOrigin.width() - d->meterPixmap.width(); + int rangePos = maxValue() - minValue(); + int valuePos = value() - minValue(); + + int returnValue = 0; + if (rangePos) + returnValue = position * valuePos / rangePos; + + return returnValue; +} + +void KSim::Progress::paintEvent(QPaintEvent *ev) +{ + KSim::Label::paintEvent(ev); + drawMeter(); +} + +void KSim::Progress::resizeEvent(QResizeEvent *ev) +{ + KSim::Label::resizeEvent(ev); + setOrigin(rect()); +} + +void KSim::Progress::drawMeter() +{ + bitBlt(this, xLocation(), 2, &d->meterPixmap); +} + +void KSim::Progress::init(int maxValue, int value, ProgressType type) +{ + d = new Private; + d->type = type; + d->value = d->minValue = 0; + d->maxValue = maxValue; + setValue(value); +} diff --git a/ksim/library/progress.h b/ksim/library/progress.h new file mode 100644 index 0000000..570894a --- /dev/null +++ b/ksim/library/progress.h @@ -0,0 +1,181 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#ifndef KSIM__PROGRESS_H +#define KSIM__PROGRESS_H + +#include "label.h" + +#include <kdemacros.h> + +namespace KSim +{ + /** + * provides a label with a progress bar meter + * @author Robbie Ward <linuxphreak@gmx.co.uk> + */ + class KDE_EXPORT Progress : public KSim::Label + { + Q_OBJECT + public: + enum ProgressType { Panel, Meter }; + /** + * constructs a KSim::Progress + * + * @param maxValue is the maximum value + * that the progress bar will show + * @param label is the text that will be displayed + * @param parent is the parent widget + */ + Progress(int maxValue, QWidget *parent, + const char *name = 0, WFlags fl = 0); + /** + * constructs a KSim::Progress + * + * @param maxValue is the maximum value + * that the progress bar will show + * @param type is the theme type + * @param label is the text that will be displayed + * @param parent is the parent widget + */ + Progress(int maxValue, int type, const QString &label, + QWidget *parent, const char *name = 0, WFlags fl = 0); + /** + * constructs a KSim::Progress + * + * @param maxValue is the maximum value + * that the progress bar will show + * @param type is the theme type + * @param label is the text that will be displayed + * @param value is the initial value to be displayed + * @param parent is the parent widget + */ + Progress(int maxValue, int type, const QString &label, + int value, QWidget *parent, const char *name = 0, + WFlags fl = 0); + /** + * constructs a KSim::Progress + * + * @param maxValue is the maximum value + * that the progress bar will show + * @param type is the theme type + * @param parent is the parent widget + */ + Progress(int maxValue, int type, QWidget *parent, + const char *name = 0, WFlags fl = 0); + /** + * constructs a KSim::Progress + * + * @param maxValue is the maximum value + * that the progress bar will show + * @param type is the theme type + * @param progressType is onr of Progress::ProgressType + * @param parent is the parent widget + */ + Progress(int maxValue, int type, + ProgressType progressType, + QWidget *parent, const char *name = 0, + WFlags fl = 0); + /** + * destructs KSim::Chart + */ + virtual ~Progress(); + + /** + * @return the current value + */ + int value() const; + /** + * @return the minimum value + */ + int minValue() const; + /** + * @return the maximum value + */ + int maxValue() const; + + /** + * @return the area that the progress meter will be drawn + */ + const QRect &rectOrigin() const; + /** + * reimplemented for internal reasons + */ + virtual void configureObject(bool repaintWidget = true); + /** + * reimplemented for internal reasons + */ + virtual QSize sizeHint() const; + + public slots: + /** + * calls KSim::Label::clear() and resets the value(), + * maxValue() and minValue() to 0 + */ + virtual void reset(); + /** + * sets the current value the progress bar will display + */ + void setValue(int); + /** + * sets the minimum value the progress bar will display + */ + void setMinValue(int); + /** + * sets the maximum value the progress bar will display + */ + void setMaxValue(int); + + protected: + /** + * sets the area that the progess bar will be drawn + */ + void setOrigin(const QRect &); + /** + * sets the progress bar pixmap + */ + void setMeterPixmap(const QPixmap &); + /** + * @return the pixel position where the meter should be drawn + */ + int xLocation() const; + /** + * reimplemented for internal reasons + */ + virtual void paintEvent(QPaintEvent *); + /** + * reimplemented for internal reasons + */ + virtual void resizeEvent(QResizeEvent *); + /** + * paints the meter image onto the widget + */ + void drawMeter(); + + private: + /** + * inits the widget + */ + void init(int, int = 0, ProgressType = Meter); + + class Private; + Private *d; + }; +} +#endif diff --git a/ksim/library/themeloader.cpp b/ksim/library/themeloader.cpp new file mode 100644 index 0000000..7c42dcd --- /dev/null +++ b/ksim/library/themeloader.cpp @@ -0,0 +1,1266 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#include "themeloader.h" +#include <ksimconfig.h> +#include "themetypes.h" +#include "common.h" + +#include <qfile.h> +#include <qstringlist.h> +#include <qvaluevector.h> +#include <qregexp.h> +#include <qapplication.h> +#include <qfileinfo.h> +#include <qdir.h> +#include <qimage.h> +#include <qbitmap.h> + +#include <kdebug.h> +#include <ksimpleconfig.h> +#include <kglobalsettings.h> +#include <kstandarddirs.h> +#include <kglobal.h> + +class KSim::Theme::Private +{ + public: + Private(const QValueVector<QString> &names, + const QStringList &list) : fileNames(names), + imageTypes(list) {} + + QStringList file; + QStringList dFile; + KConfig *globalReader; + QString altTheme; + QString location; + const QValueVector<QString> &fileNames; + const QStringList &imageTypes; + int alternative; + int font; + bool recolour; + + QString readOption(const QString &entry, + bool useGlobal = true, + const QString &defValue = QString::null) + { + QString text; + QStringList::ConstIterator it; + for (it = file.begin(); it != file.end(); ++it) { + if ((*it).find(entry) != -1) { + text = QStringList::split("=", (*it))[1].stripWhiteSpace(); + } + } + + if (!text.isEmpty() || dFile.isEmpty()) + return text; + + QStringList::ConstIterator it2; + for (it2 = dFile.begin(); it2 != dFile.end(); ++it) { + if ((*it2).find(entry) != -1) { + text = QStringList::split("=", (*it2))[1].stripWhiteSpace(); + } + } + + if (!text.isEmpty()) + return text; + + if (!globalReader || !useGlobal) + return defValue; + + text = globalReader->readEntry(entry, defValue); + return text; + } +}; + +class KSim::ThemeLoader::Private +{ + public: + QValueVector<QString> fileNames; + QStringList imageTypes; + KConfig *globalReader; + bool recolour; + QColor pixelColour; +}; + +bool KSim::Theme::operator==(const KSim::Theme &rhs) const +{ + return d == rhs.d; +} + +bool KSim::Theme::operator!=(const KSim::Theme &rhs) const +{ + return !(operator==(rhs)); +} + +KSim::Theme &KSim::Theme::operator=(const KSim::Theme &rhs) +{ + if (*this == rhs) + return *this; + + delete d; + d = rhs.d; + return *this; +} + +KSim::Theme::~Theme() +{ + delete d; +} + +const QString &KSim::Theme::path() const +{ + return d->location; +} + +QString KSim::Theme::name() const +{ + QString name = d->location; + if (name.endsWith("/")) + name.remove(name.length() - 1, 1); + + return name.remove(0, name.findRev("/") + 1); +} + +QString KSim::Theme::author() const +{ + QString author(d->readOption("author", false)); + return author.replace(QRegExp("\""), QString::null); +} + +int KSim::Theme::fontItem() const +{ + return d->font; +} + +int KSim::Theme::alternative() const +{ + return d->alternative; +} + +int KSim::Theme::alternatives() const +{ + return d->readOption("theme_alternatives").toInt(); +} + +int KSim::Theme::chartWidthRef(int defValue) const +{ + return internalNumEntry("chart_width_ref", defValue); +} + +int KSim::Theme::chartWidthMin(int defValue) const +{ + return internalNumEntry("chart_width_min", defValue); +} + +bool KSim::Theme::scaling(bool defValue) const +{ + return internalNumEntry("allow_scaling", defValue); +} + +int KSim::Theme::frameTopHeight(int defValue) const +{ + return KMIN(2, internalNumEntry("frame_top_height", defValue)); +} + +int KSim::Theme::frameBottomHeight(int defValue) const +{ + return KMIN(2, internalNumEntry("frame_bottom_height", defValue)); +} + +int KSim::Theme::frameLeftWidth(int defValue) const +{ + return KMIN(2, internalNumEntry("frame_left_width", defValue)); +} + +int KSim::Theme::frameRightWidth(int defValue) const +{ + return KMIN(2, internalNumEntry("frame_right_width", defValue)); +} + +QRect KSim::Theme::frameTopBorder(const QRect &defValue) const +{ + return internalRectEntry("frame_top_border", defValue); +} + +QRect KSim::Theme::frameBottomBorder(const QRect &defValue) const +{ + return internalRectEntry("frame_bottom_border", defValue); +} + +QRect KSim::Theme::frameLeftBorder(const QRect &defValue) const +{ + return internalRectEntry("frame_left_border", defValue); +} + +QRect KSim::Theme::frameRightBorder(const QRect &defValue) const +{ + return internalRectEntry("frame_right_border", defValue); +} + +QColor KSim::Theme::chartInColour(const QColor &defValue) const +{ + if (d->recolour) + return QApplication::palette().active().background(); + + return internalColourEntry("chart_in_color", defValue); +} + +QColor KSim::Theme::chartInColourGrid(const QColor &defValue) const +{ + return internalColourEntry("chart_in_color_grid", defValue); +} + +QColor KSim::Theme::chartOutColour(const QColor &defValue) const +{ + if (d->recolour) + return QApplication::palette().active().background(); + + return internalColourEntry("chart_out_color", defValue); +} + +QColor KSim::Theme::chartOutColourGrid(const QColor &defValue) const +{ + return internalColourEntry("chart_out_color_grid", defValue); +} + +bool KSim::Theme::bgGridMode(bool defValue) const +{ + return internalNumEntry("bg_grid_mode", defValue); +} + +int KSim::Theme::rxLedX(int defValue) const +{ + return internalNumEntry("rx_led_x", defValue); +} + +int KSim::Theme::rxLedY(int defValue) const +{ + return internalNumEntry("rx_led_y", defValue); +} + +int KSim::Theme::txLedX(int defValue) const +{ + return internalNumEntry("tx_led_x", defValue); +} + +int KSim::Theme::txLedY(int defValue) const +{ + return internalNumEntry("tx_led_y", defValue); +} + +int KSim::Theme::mailFrames(int defValue) const +{ + return internalNumEntry("decal_mail_frames", defValue); +} + +int KSim::Theme::mailDelay(int defValue) const +{ + return internalNumEntry("decal_mail_delay", defValue); +} + +int KSim::Theme::krellSliderDepth(int defValue) const +{ + return internalNumEntry("krell_slider_depth", defValue); +} + +int KSim::Theme::krellSliderXHot(int defValue) const +{ + return internalNumEntry("krell_slider_x_hot", defValue); +} + +QRect KSim::Theme::sliderPanel(const QRect &defValue) const +{ + return internalRectEntry("bg_slider_panel_border", defValue); +} + +QRect KSim::Theme::sliderMeter(const QRect &defValue) const +{ + return internalRectEntry("bg_slider_meter_border", defValue); +} + +QRect KSim::Theme::timerBorder(const QRect &defValue) const +{ + return internalRectEntry("bg_timer_border", defValue); +} + +QRect KSim::Theme::buttonPanelBorder(const QRect &defValue) const +{ + return internalRectEntry("button_panel_border", defValue); +} + +QRect KSim::Theme::buttonMeterBorder(const QRect &defValue) const +{ + return internalRectEntry("button_meter_border", defValue); +} + +QFont KSim::Theme::largeFont() const +{ + QString font(internalStringEntry("large_font", QString::null)); + + if (font.isEmpty()) + return QApplication::font(); + + QFont themeFont; + themeFont.setRawName(font.replace(QRegExp("\""), QString::null)); + return themeFont; +} + +QFont KSim::Theme::normalFont() const +{ + QString font(internalStringEntry("normal_font", QString::null)); + + if (font.isEmpty()) + return QApplication::font(); + + QFont themeFont; + themeFont.setRawName(font.replace(QRegExp("\""), QString::null)); + return themeFont; +} + +QFont KSim::Theme::smallFont() const +{ + QString font(internalStringEntry("small_font", QString::null)); + + if (font.isEmpty()) + return QApplication::font(); + + QFont themeFont; + themeFont.setRawName(font.replace(QRegExp("\""), QString::null)); + return themeFont; +} + +QFont KSim::Theme::currentFont() const +{ + switch (fontItem()) { + case 0: + return smallFont(); + break; + case 1: + return normalFont(); + break; + case 2: + return largeFont(); + break; + case 3: + return KSim::ThemeLoader::currentFont(); + break; + case 4: + return KGlobalSettings::generalFont(); + break; + } + + return QFont(); +} + +QString KSim::Theme::meterPixmap(int type, bool useDefault) const +{ + QString imageFile = createType(type, d->location); + QString text; + QString file = d->fileNames[7]; + + QStringList::ConstIterator it; + for (it = d->imageTypes.begin(); it != d->imageTypes.end(); ++it) { + if (QFile::exists(imageFile + file + d->altTheme + "." + *it)) { + text = imageFile + file + d->altTheme + "." + *it; + break; + } + else + if (QFile::exists(d->location + file + d->altTheme + "." + *it)) { + text = d->location + file + d->altTheme + "." + *it; + break; + } + } + + if (text.isNull() && useDefault) + return KSim::ThemeLoader::defaultUrl() + d->fileNames[7] + ".png"; + + return text; +} + +QString KSim::Theme::panelPixmap(int type, bool useDefault) const +{ + QString imageFile = createType(type, d->location); + QString text; + QString file = d->fileNames[6]; + + QStringList::ConstIterator it; + for (it = d->imageTypes.begin(); it != d->imageTypes.end(); ++it) { + if (QFile::exists(imageFile + file + d->altTheme + "." + *it)) { + text = imageFile + file + d->altTheme + "." + *it; + break; + } + else + if (QFile::exists(d->location + file + d->altTheme + "." + *it)) { + text = d->location + file + d->altTheme + "." + *it; + break; + } + } + + if (text.isNull() && useDefault) + return KSim::ThemeLoader::defaultUrl() + d->fileNames[6] + ".png"; + + return text; +} + +QString KSim::Theme::ledPixmap(int type, bool useDefault) const +{ + QString imageFile = createType(type, d->location); + QString text; + QString file = d->fileNames[30]; + + QStringList::ConstIterator it; + for (it = d->imageTypes.begin(); it != d->imageTypes.end(); ++it) { + if (QFile::exists(imageFile + file + d->altTheme + "." + *it)) { + text = imageFile + file + d->altTheme + "." + *it; + break; + } + else + if (QFile::exists(d->location + file + d->altTheme + "." + *it)) { + text = d->location + file + d->altTheme + "." + *it; + break; + } + } + + if (text.isNull() && useDefault) + return KSim::ThemeLoader::defaultUrl() + d->fileNames[30] + ".png"; + + return text; +} + +QString KSim::Theme::framePixmap(int type, bool useDefault) const +{ + QString text; + QString file; + + switch (type) { + case Types::TopFrame: + file = d->fileNames[0]; + break; + case Types::BottomFrame: + file = d->fileNames[1]; + break; + case Types::LeftFrame: + file = d->fileNames[2]; + break; + case Types::RightFrame: + file = d->fileNames[3]; + break; + } + + QStringList::ConstIterator it; + for (it = d->imageTypes.begin(); it != d->imageTypes.end(); ++it) { + if (QFile::exists(d->location + file + d->altTheme + "." + *it)) { + text = d->location + file + d->altTheme + "." + *it; + break; + } + } + + if (text.isNull() && useDefault) { + switch (type) { + case Types::TopFrame: + return KSim::ThemeLoader::defaultUrl() + d->fileNames[0] + ".png"; + break; + case Types::BottomFrame: + return KSim::ThemeLoader::defaultUrl() + d->fileNames[1] + ".png"; + break; + case Types::LeftFrame: + return KSim::ThemeLoader::defaultUrl() + d->fileNames[2] + ".png"; + break; + case Types::RightFrame: + return KSim::ThemeLoader::defaultUrl() + d->fileNames[3] + ".png"; + break; + } + } + + return text; +} + +QString KSim::Theme::chartPixmap(bool useDefault) const +{ + return loader(4, useDefault); +} + +QString KSim::Theme::gridPixmap(bool useDefault) const +{ + return loader(5, useDefault); +} + +QString KSim::Theme::krellPanelPixmap(bool useDefault) const +{ + return loader(14, useDefault); +} + +QString KSim::Theme::krellMeterPixmap(bool useDefault) const +{ + return loader(15, useDefault); +} + +QString KSim::Theme::krellSliderPixmap(bool useDefault) const +{ + return loader(16, useDefault); +} + +QString KSim::Theme::dataInPixmap(bool useDefault) const +{ + return loader(18, useDefault); +} + +QString KSim::Theme::dataOutPixmap(bool useDefault) const +{ + return loader(20, useDefault); +} + +QString KSim::Theme::mailPixmap(bool useDefault) const +{ + QString imageFile = createType(KSim::Types::Mail, d->location); + QString text; + QString file = d->fileNames[25]; + + QStringList::ConstIterator it; + for (it = d->imageTypes.begin(); it != d->imageTypes.end(); ++it) { + if (QFile::exists(imageFile + file + d->altTheme + "." + *it)) { + text = imageFile + file + d->altTheme + "." + *it; + break; + } + else + if (QFile::exists(d->location + file + d->altTheme + "." + *it)) { + text = d->location + file + d->altTheme + "." + *it; + break; + } + } + + if (text.isNull() && useDefault) + return KSim::ThemeLoader::defaultUrl() + + createType(KSim::Types::Mail, QString::null) + file + ".png"; + + return text; +} + +QPixmap KSim::Theme::splitPixmap(PixmapType type, uint itemNo, + bool useDefault) const +{ + return pixmapToList(type, itemNo, useDefault)[itemNo]; +} + +QValueList<QPixmap> KSim::Theme::pixmapToList(PixmapType type, + int limitAmount, bool useDefault) const +{ + QImage image; + int xOffset = 0; + int yOffset = 0; + int depth = 0; + + switch (type) { + case KrellPanel: + depth = readIntEntry("StylePanel", "*.krell_depth"); + xOffset = readIntEntry("StylePanel", "*.krell_x_hot"); + yOffset = readIntEntry("StylePanel", "*.krell_yoff"); + image.load(krellPanelPixmap(useDefault)); + kdDebug(2003) << "KSim::Theme: type = KrellPanel" << endl; + break; + case KrellMeter: + depth = readIntEntry("StyleMeter", "*.krell_depth"); + xOffset = readIntEntry("StyleMeter", "*.krell_x_hot"); + yOffset = readIntEntry("StyleMeter", "*.krell_yoff"); + image.load(krellMeterPixmap(useDefault)); + kdDebug(2003) << "KSim::Theme: type = KrellMeter" << endl; + break; + case KrellSlider: + depth = krellSliderDepth(); + image.load(krellSliderPixmap(useDefault)); + kdDebug(2003) << "KSim::Theme: type = KrellSlider" << endl; + break; + default: + return QValueList<QPixmap>(); + break; + } + + if (image.isNull()) + return QValueList<QPixmap>(); + + QValueList<QPixmap> list; + int size = image.height(); + if (depth) + size = image.height() / depth; + + KSim::ThemeLoader::self().reColourImage(image); + QPixmap pixmap = image; + QPixmap newPixmap(image.width() - xOffset, size); + + for (int i = 0; i < (depth + 1); ++i) { + newPixmap.fill(); + + if (pixmap.mask()) { + QBitmap mask(newPixmap.size()); + bitBlt(&mask, 0, 0, pixmap.mask(), xOffset, yOffset, + image.width() - xOffset, size); + newPixmap.setMask(mask); + } + + bitBlt(&newPixmap, 0, 0, &pixmap, xOffset, yOffset, + image.width() - xOffset, size); + + list.append(newPixmap); + + if (limitAmount == i) + break; + } + + kdDebug(2003) << "KSim::Theme: size = " << size << endl; + kdDebug(2003) << "KSim::Theme: depth = " << depth << endl; + kdDebug(2003) << "KSim::Theme: xOffset = " << xOffset << endl; + kdDebug(2003) << "KSim::Theme: yOffset = " << xOffset << endl; + + return list; +} + +int KSim::Theme::transparency(const QString &itemType, + const QString &entry) const +{ + return readIntEntry(itemType, entry); +} + +bool KSim::Theme::textShadow(const QString &itemType, + const QString &entry) const +{ + if (d->recolour) + return false; + + QString shadow = readEntry(itemType, entry); + if (shadow.isEmpty() || shadow.findRev("none") != -1) + return false; + + return true; +} + +QColor KSim::Theme::shadowColour(const QString &itemType, + const QString &entry) const +{ + return readColourEntry(itemType, entry, 1); +} + +QColor KSim::Theme::textColour(const QString &itemType, + const QString &entry) const +{ + if (d->recolour) + return KGlobalSettings::textColor(); + + return readColourEntry(itemType, entry, 0); +} + +int KSim::Theme::readIntEntry(const QString &itemType, + const QString &entry) const +{ + QString entryName = itemType + " " + entry; + return internalNumEntry(entryName, 0); +} + +QRect KSim::Theme::readRectEntry(const QString &itemType, + const QString &entry) const +{ + QString entryName = itemType + " " + entry; + return internalRectEntry(entryName, QRect()); +} + +QString KSim::Theme::readEntry(const QString &itemType, + const QString &entry) const +{ + QString entryName = itemType + " " + entry; + return internalStringEntry(entryName, QString::null); +} + +QString KSim::Theme::readColourEntry(const QString &itemType, + const QString &entry, int row) const +{ + QString color = readEntry(itemType, entry); + if (color.isEmpty()) + color = QString::fromLatin1("#ffffff #ffffff"); + + return QStringList::split(' ', color)[row]; +} + +QFont KSim::Theme::readFontEntry(const QString &itemType, + const QString &entry) const +{ + const QString &font = readEntry(itemType, entry); + + // If only there was a better way of doing this + if (font == "small_font") + return smallFont(); + else + if (font == "normal_font") + return normalFont(); + else + if (font == "large_font") + return largeFont(); + + return QFont(); +} + +bool KSim::Theme::fontColours(int type, const QString &string, QFont &font, + QColor &text, QColor &shadow, bool &showShadow) const +{ + QString key = KSim::Types::typeToString(type, false); + bool repaint = false; + + // set colours from the string 'key' + if (!readEntry(string, key + ".textcolor").isEmpty()) { + text= textColour(string, key + ".textcolor"); + shadow = shadowColour(string, key + ".textcolor"); + showShadow = textShadow(string, key + ".textcolor"); + repaint = true; + } + else { + text= textColour(string, "*.textcolor"); + shadow = shadowColour(string, "*.textcolor"); + showShadow = textShadow(string, "*.textcolor"); + } + + // set fonts from the string 'key' + if (!readEntry(string, key + ".font").isEmpty()) { + if (KSim::ThemeLoader::currentFontItem() != 3) { + font = readFontEntry(string, key + ".font"); + repaint = true; + } + } + else { + font = currentFont(); + } + + return repaint; +} + +bool KSim::Theme::fontColours(const KSim::Base *const base, QFont &font, + QColor &text, QColor &shadow, bool &showShadow) const +{ + if (!base) + return false; + + return fontColours(base->type(), base->configString(), font, + text, shadow, showShadow); +} + +KSim::Theme::Theme() +{ + d = 0; +} + +KSim::Theme::Theme(const QString &url, const QString &fileName, int alt, + const QValueVector<QString> &vector, const QStringList &list, + KConfig *globalReader) +{ + create(vector, list, globalReader); + init(url, fileName, alt); + + KSim::Config::config()->setGroup("Misc"); + d->recolour = KSim::Config::config()->readBoolEntry("ReColourTheme", false); +} + +void KSim::Theme::create(const QValueVector<QString> &vector, + const QStringList &list, KConfig *globalReader) +{ + d = new Private(vector, list); + d->globalReader = globalReader; +} + +void KSim::Theme::init(const QString &url, const QString &fileName, int alt) +{ + d->altTheme = KSim::ThemeLoader::alternativeAsString(alt); + d->location = url; + d->alternative = alt; + d->font = KSim::ThemeLoader::currentFontItem(); + + d->file = QStringList::split("\n", parseConfig(url, fileName)); + + if (alt != 0) + d->dFile = QStringList::split("\n", parseConfig(url, "gkrellmrc")); +} + +void KSim::Theme::reparse(const QString &url, const QString &fileName, int alt) +{ + init(url, fileName, alt); +} + +QString KSim::Theme::parseConfig(const QString &url, + const QString &fileName) +{ + return KSim::ThemeLoader::self().parseConfig(url, fileName); +} + +QString KSim::Theme::loader(int value, bool useDefault) const +{ + QString text; + QString file = d->fileNames[value]; + + QStringList::ConstIterator it; + for (it = d->imageTypes.begin(); it != d->imageTypes.end(); ++it) { + if (QFile::exists(d->location + file + d->altTheme + "." + *it)) { + text = d->location + file + d->altTheme + "." + *it; + break; + } + } + + if (text.isNull() && useDefault) + return KSim::ThemeLoader::defaultUrl() + d->fileNames[value] + ".png"; + + return text; +} + +QString KSim::Theme::createType(int type, const QString &text) const +{ + if (type == Types::None) + return text; + + return text + KSim::Types::typeToString(type); +} + +void KSim::Theme::setRecolour(bool value) +{ + if (!d) + return; + + d->recolour = value; +} + +// Keep the ugliness here to make the rest +// of the class readable +int KSim::Theme::internalNumEntry(const QString &entry, int defValue) const +{ + return d->readOption(entry, true, QString::number(defValue)).toInt(); +} + +QRect KSim::Theme::internalRectEntry(const QString &entry, + const QRect &defValue) const +{ + QString rect; + rect += QString::number(defValue.left()); + rect += ","; + rect += QString::number(defValue.top()); + rect += ","; + rect += QString::number(defValue.width()); + rect += ","; + rect += QString::number(defValue.height()); + + QStringList list = QStringList::split(",", d->readOption(entry, true, rect)); + QRect rect2(list[0].toInt(), list[1].toInt(), list[2].toInt(), list[3].toInt()); + + return rect2; +} + +QColor KSim::Theme::internalColourEntry(const QString &entry, + const QColor &defValue) const +{ + return d->readOption(entry, true, defValue.name()); +} + +QString KSim::Theme::internalStringEntry(const QString &entry, + const QString &defValue) const +{ + return d->readOption(entry, true, defValue); +} + +// check if the dir is writable, if not generate the new file in the home dir +#define KSIM_THEME_URL(url) \ +{ \ +} + +KSim::ThemeLoader *KSim::ThemeLoader::m_self = 0; // initialize pointer +KSim::ThemeLoader &KSim::ThemeLoader::self() +{ + if (!m_self) { // is it the first call? + m_self = new KSim::ThemeLoader; // create sole instance + qAddPostRoutine(cleanup); + } + + return *m_self; // address of sole instance +} + +bool KSim::ThemeLoader::isDifferent() const +{ + // if the theme path, theme alternative or the + // specified font has changed then we should + // return true, else false + + KSim::Config::config()->setGroup("Misc"); + bool recolour = KSim::Config::config()->readBoolEntry("ReColourTheme", false); + + return (current().path() != currentUrl() + || current().alternative() != currentAlternative() + || current().fontItem() != currentFontItem() + || d->recolour != recolour); +} + +void KSim::ThemeLoader::reload() +{ + reColourItems(); + grabColour(); + + if (!isDifferent()) + return; + + if (currentUrl() != defaultUrl()) { + if (!d->globalReader) + d->globalReader = new KConfig(defaultUrl() + "gkrellmrc_ksim"); + } + else { + delete d->globalReader; + d->globalReader = 0; + } + + if (m_theme.d) + m_theme.d->globalReader = d->globalReader; + + QString fileName = QString::fromLatin1("gkrellmrc") + alternativeAsString(); + m_theme.reparse(currentUrl(), fileName, currentAlternative()); +} + +const KSim::Theme &KSim::ThemeLoader::current() const +{ + return m_theme; +} + +KSim::Theme KSim::ThemeLoader::theme(const QString &url, + const QString &rcFile, int alt) const +{ + return KSim::Theme(url, rcFile, alt, d->fileNames, + d->imageTypes, d->globalReader); +} + +void KSim::ThemeLoader::reColourImage(QImage &image) +{ + if (!d->recolour || image.isNull()) + return; + + QColor color = QApplication::palette().active().background(); + QImage output(image.width(), image.height(), 32); + output.setAlphaBuffer(image.hasAlphaBuffer()); + + Q_UINT32 r = color.red(); + Q_UINT32 g = color.green(); + Q_UINT32 b = color.blue(); + Q_UINT32 *write = reinterpret_cast<Q_UINT32 *>(output.bits()); + Q_UINT32 *read = reinterpret_cast<Q_UINT32 *>(image.bits()); + int size = image.width() * image.height(); + + for (int pos = 0; pos < size; pos++) + { + QRgb basePix = static_cast<QRgb>(*read); + + // Here, we assume that source is really gray, so R=G=B=I + // Use blue since it's very easy to extract. + Q_UINT32 i = qBlue(basePix); + + Q_UINT32 cr = (r * i + 128) >> 8; // Fixed point.. + Q_UINT32 cg = (g * i + 128) >> 8; + Q_UINT32 cb = (b * i + 128) >> 8; + + Q_UINT32 alpha = qAlpha(basePix); + *write = qRgba(cr, cg, cb, alpha); + write++; + read++; + } + + image = output; +} + +QString KSim::ThemeLoader::parseConfig(const QString &url, + const QString &fileName) +{ + QFile origFile(url + fileName); + + if (!origFile.open(IO_ReadOnly)) + return QString::null; + + QTextStream origStream(&origFile); + QString text; + QRegExp reg("\\*"); // regexp for '*' chars + QRegExp number("[0-9]+"); // regexp for all numbers + QRegExp numbers("[0-9]+,[0-9]+,[0-9]+,[0-9]+"); // regexp for int,int,int,int + QRegExp minus("[a-zA-Z]+ \\- [a-zA-Z]+"); // regexp for 'someText - someText' + while (!origStream.atEnd()) { + QString line(origStream.readLine().simplifyWhiteSpace()); + + if (line.find(reg) == 0) // find the location of the * comments + // replace all * comments with # comments so KConfig doesn't complain + line.replace(reg, "#"); + + if (line.find("#") == -1) { // find the location of the string 'gkrellmms' + if (line.findRev("=") == -1) { // if found we check for the string '=' + int numLoc = line.findRev(numbers); + if (numLoc != -1) + // if '=' doesn't exist we add one so KConfig doesn't complain + line.insert(numLoc, " = "); + + numLoc = line.findRev(number); + if (numLoc != -1) + // if '=' doesn't exist we add one so KConfig doesn't complain + line.insert(numLoc, " = "); + + numLoc = line.findRev(minus); + if (numLoc != -1) + // replace the '-' with an '=' so KConfig doesn't get confused + line.replace(QRegExp("-"), "="); + } + } + + text.append(line).append('\n'); + } + + return text; +} + +// GKrellM themes seem to be rather inconsistant +// so the following code changes the dir structure +// of a theme to be more consistant, but the dir structure +// is still compliant with GKrellM. +void KSim::ThemeLoader::parseDir(const QString &url, int alt) +{ + if ( !QFileInfo( url ).isWritable() && currentName() != "ksim" ) + { + QString homePath = QDir::current().path(); + homePath = locateLocal( "data", "ksim" ) + + QString::fromLatin1( "/themes" ) + + homePath.right( homePath.length() + - homePath.findRev( QRegExp( "\\/" ), + homePath.length() ) ); + + if ( !QFile::exists( homePath ) ) + KStandardDirs::makeDir( homePath ); + + kdWarning() << "Cant write to current dir, setting dir to " + << homePath << endl; + + QDir::setCurrent( homePath ); + } + + int alternatives = ++alt; + + QStringList formats; + QStringList panels; + QStringList meters; + + formats << "png" << "jpg" << "jpeg" << "gif" << "xpm"; + panels << "inet" << "net" << "proc" << "cpu" << "disk"; + meters << "mem" << "fs" << "mail" << "apm" << "uptime" + << "clock" << "cal" << "timer" << "host" << "swap"; + + QDir directory; + for (int i = 0; i < alternatives; ++i) { + QString altString = KSim::ThemeLoader::alternativeAsString(i); + if (alternatives == 1 || i == 0) + altString = QString::null; + + QStringList::ConstIterator format; + for (format = formats.begin(); format != formats.end(); ++format) { + // go through the meters array and move the files to the correct dir/filename + QStringList::Iterator meter; + for (meter = meters.begin(); meter != meters.end(); ++meter) { + QString bgMeter = QString::fromLatin1("bg_meter_"); + if (QFile::exists(bgMeter + (*meter) + altString + "." + (*format))) { + if (KStandardDirs::makeDir(url + (*meter))) + directory.rename(bgMeter + (*meter) + altString + "." + (*format), + (*meter) + "/bg_meter" + altString + "." + (*format)); + } + } + + // go through the panels array and move the files to the correct dir/filename + QStringList::ConstIterator panel; + for (panel = panels.begin(); panel != panels.end(); ++panel) { + QString bgPanel = QString::fromLatin1("bg_panel_"); + if (QFile::exists(bgPanel + (*panel) + altString + "." + (*format))) { + if (KStandardDirs::makeDir(url + (*panel))) + directory.rename(bgPanel + (*panel) + altString + "." + (*format), + (*panel) + "/bg_panel" + altString + "." + (*format)); + } + } + + // fix stupid themes that have a bg_panel image in the host dir + QString tempFile = QString::fromLatin1("host/bg_panel"); + if (QFile::exists(tempFile + altString + "." + (*format))) + directory.rename(tempFile + altString + "." + (*format), "host/bg_meter" + + altString + "." + (*format)); + + // move decal_net_leds* to the net folder to be more consistant + tempFile = QString::fromLatin1("decal_net_leds"); + if (QFile::exists(tempFile + altString + "." + (*format))) { + if (KStandardDirs::makeDir(url + "net")) + directory.rename(tempFile + altString + "." + (*format), + "net/decal_net_leds" + altString + "." + (*format)); + } + } + } +} + +void KSim::ThemeLoader::validate() +{ + if (!QFile::exists(currentUrl())) { + KSim::Config::config()->setGroup("Theme"); + KSim::Config::config()->writeEntry("Name", "ksim"); + KSim::Config::config()->writeEntry("Alternative", 0); + KSim::Config::config()->sync(); + } +} + +void KSim::ThemeLoader::themeColours(QWidget *widget) +{ + widget->setEraseColor(d->pixelColour); +} + +QString KSim::ThemeLoader::currentName() +{ + KSim::Config::config()->setGroup("Theme"); + return KSim::Config::config()->readEntry("Name", "ksim"); +} + +QString KSim::ThemeLoader::currentUrl() +{ + KSim::Config::config()->setGroup("Theme"); + QString folder(KSim::Config::config()->readEntry("Name")); + folder.prepend("ksim/themes/").append("/"); + QString dirName(KGlobal::dirs()->findResourceDir("data", folder)); + dirName += folder; + + return dirName; +} + +QString KSim::ThemeLoader::defaultUrl() +{ + return KGlobal::dirs()->findDirs("data", "ksim/themes/ksim").first(); +} + +int KSim::ThemeLoader::currentAlternative() +{ + KSim::Config::config()->setGroup("Theme"); + int alternative = KSim::Config::config()->readNumEntry("Alternative"); + + if ( alternative > self().current().alternatives() ) + alternative = self().current().alternatives(); + + return alternative; +} + +QString KSim::ThemeLoader::alternativeAsString(int alt) +{ + int alternative = (alt == -1 ? currentAlternative() : alt); + return (alternative == 0 ? QString::null : QString::fromLatin1("_") + + QString::number(alternative)); +} + +QFont KSim::ThemeLoader::currentFont() +{ + if (currentFontItem() != 3) + return self().current().currentFont(); + + KSim::Config::config()->setGroup("Theme"); + return KSim::Config::config()->readFontEntry("Font"); +} + +int KSim::ThemeLoader::currentFontItem() +{ + KSim::Config::config()->setGroup("Theme"); + return KSim::Config::config()->readNumEntry("FontItem", 0); +} + +KSim::ThemeLoader::ThemeLoader() +{ + m_self = this; + + d = new Private; + d->imageTypes << "png" << "jpg" << "jpeg" << "xpm" << "gif"; + + if (currentUrl() != defaultUrl()) + d->globalReader = new KConfig(defaultUrl() + "gkrellmrc_ksim"); + else + d->globalReader = 0; + + d->fileNames.resize(31); + d->fileNames[0] = "frame_top"; + d->fileNames[1] = "frame_bottom"; + d->fileNames[2] = "frame_left"; + d->fileNames[3] = "frame_right"; + d->fileNames[4] = "bg_chart"; + d->fileNames[5] = "bg_grid"; + d->fileNames[6] = "bg_panel"; + d->fileNames[7] = "bg_meter"; + d->fileNames[8] = "bg_slider_panel"; + d->fileNames[9] = "bg_slider_meter"; + d->fileNames[10] = "button_panel_in"; + d->fileNames[11] = "button_panel_out"; + d->fileNames[12] = "button_meter_in"; + d->fileNames[13] = "button_meter_out"; + d->fileNames[14] = "krell_panel"; + d->fileNames[15] = "krell_meter"; + d->fileNames[16] = "krell_slider"; + d->fileNames[17] = "decal_misc"; + d->fileNames[18] = "data_in"; + d->fileNames[19] = "data_in_grid"; + d->fileNames[20] = "data_out"; + d->fileNames[21] = "data_out_grid"; + d->fileNames[22] = "krell"; + d->fileNames[23] = "spacer_top"; + d->fileNames[24] = "spacer_bottom"; + d->fileNames[25] = "decal_mail"; + d->fileNames[26] = "krell_penguin"; + d->fileNames[27] = "bg_volt"; + d->fileNames[28] = "decal_timer_button"; + d->fileNames[29] = "bg_timer"; + d->fileNames[30] = "decal_net_leds"; + + m_theme.create(d->fileNames, d->imageTypes, d->globalReader); + + QString fileName = QString::fromLatin1("gkrellmrc") + alternativeAsString(); + m_theme.init(currentUrl(), fileName, currentAlternative()); + + reColourItems(); + grabColour(); +} + +KSim::ThemeLoader::~ThemeLoader() +{ + delete d->globalReader; + delete d; +} + +void KSim::ThemeLoader::cleanup() +{ + if (!m_self) + return; + + delete m_self; + m_self = 0; +} + +void KSim::ThemeLoader::reColourItems() +{ + KSim::Config::config()->setGroup("Misc"); + d->recolour = KSim::Config::config()->readBoolEntry("ReColourTheme", false); + m_theme.setRecolour(d->recolour); +} + +void KSim::ThemeLoader::grabColour() +{ + KSim::Config::config()->setGroup("Theme"); + QPoint pos(2, 2); + pos = KSim::Config::config()->readPointEntry("PixelLocation", &pos); + + QImage image(current().meterPixmap(Types::None)); + reColourImage(image); + d->pixelColour = image.pixel(pos.x(), pos.y()); +} diff --git a/ksim/library/themeloader.h b/ksim/library/themeloader.h new file mode 100644 index 0000000..c20afe0 --- /dev/null +++ b/ksim/library/themeloader.h @@ -0,0 +1,511 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#ifndef THEMELOADER_H +#define THEMELOADER_H + +#include <qstring.h> +#include <qrect.h> +#include <qcolor.h> +#include <qfont.h> +#include <qvaluelist.h> + +#include <kdemacros.h> + +class QStringList; +template<class> class QValueVector; +class KConfig; +class QWidget; + +namespace KSim +{ + class Base; + + /** + * a class containing various information + * about a theme, use KSim::ThemeLoader to + * get an instance + * @author Robbie Ward <linuxphreak@gmx.co.uk> + * @short Provides a loader for the themes + */ + class KDE_EXPORT Theme + { + friend class ThemeLoader; + public: + enum PixmapType { KrellPanel = 0, KrellMeter, KrellSlider }; + ~Theme(); + bool operator==(const KSim::Theme &rhs) const; + bool operator!=(const KSim::Theme &rhs) const; + KSim::Theme &operator=(const KSim::Theme &rhs); + /** + * @return the theme path + */ + const QString &path() const; + /** + * @return the name of the theme + */ + QString name() const; + /** + * @return the author of the theme + */ + QString author() const; + /** + * @return the set font item for the theme + */ + int fontItem() const; + /** + * @return the amount of alternatives the theme has + */ + int alternative() const; + /** + * @return the amount of alternatives the theme has + */ + int alternatives() const; + /** + * @return the width leds should be scaled to (if scaling() returns true) + */ + int chartWidthRef(int defValue = 0) const; + int chartWidthMin(int defValue = 0) const; + /** + * @return true if sacling should be enabled + */ + bool scaling(bool defValue = false) const; + /** + * @return the height of the top frame + */ + int frameTopHeight(int defValue = 0) const; + /** + * @return the height of the bottom frame + */ + int frameBottomHeight(int defValue = 0) const; + /** + * @return the width of the left frame + */ + int frameLeftWidth(int defValue = 0) const; + /** + * @return the width of the right frame + */ + int frameRightWidth(int defValue = 0) const; + /** + * @return a rect of the top frame border + */ + QRect frameTopBorder(const QRect &defValue = QRect()) const; + /** + * @return a rect of the bottom frame border + */ + QRect frameBottomBorder(const QRect &defValue = QRect()) const; + /** + * @return a rect of the left frame border + */ + QRect frameLeftBorder(const QRect &defValue = QRect()) const; + /** + * @return a rect of the right frame border + */ + QRect frameRightBorder(const QRect &defValue = QRect()) const; + /** + * @return the color of the chart in + */ + QColor chartInColour(const QColor &defValue = QColor()) const; + /** + * @return the color of the chart in grid + */ + QColor chartInColourGrid(const QColor &defValue = QColor()) const; + /** + * @return the color of the chart out + */ + QColor chartOutColour(const QColor &defValue = QColor()) const; + /** + * @return the color of the chart out grid + */ + QColor chartOutColourGrid(const QColor &defValue = QColor()) const; + /** + * if false then the grid lines should be drawn at the + * top and bottom of the graphs + */ + bool bgGridMode(bool defValue = false) const; + /** + * @return the X location of the receive led + */ + int rxLedX(int defValue = 0) const; + /** + * @return the Y location of the receive led + */ + int rxLedY(int defValue = 0) const; + /** + * @return the X location of the send led + */ + int txLedX(int defValue = 0) const; + /** + * @return the Y location of the send led + */ + int txLedY(int defValue = 0) const; + /** + * @return the amount of mail frames + */ + int mailFrames(int defValue = 0) const; + /** + * @return the mail check delay + */ + int mailDelay(int defValue = 0) const; + /** + * @return the slider depth + */ + int krellSliderDepth(int defValue = 7) const; + /** + * @return the vertical location of the start of the image + */ + int krellSliderXHot(int defValue = 0) const; + /** + * @return the area for the slider panel + */ + QRect sliderPanel(const QRect &defValue = QRect()) const; + /** + * @return the area for the slider meter + */ + QRect sliderMeter(const QRect &defValue = QRect()) const; + /** + * @return the border for the timer label/button + */ + QRect timerBorder(const QRect &defValue = QRect()) const; + /** + * @return the border for the panel button + */ + QRect buttonPanelBorder(const QRect &defValue = QRect()) const; + /** + * @return the border for the meter button + */ + QRect buttonMeterBorder(const QRect &defValue = QRect()) const; + /** + * @return the large font that the theme specifies + */ + QFont largeFont() const; + /** + * @return the normal font that the theme specifies + */ + QFont normalFont() const; + /** + * @return the small font that the theme specifies + */ + QFont smallFont() const; + /** + * @return the current font to be used + * according to fontItem() + */ + QFont currentFont() const; + /** + * @return the meter image (bg_meter.[png|jpg|gif]) + * of the current theme, if type is specified then it will + * look in the folder type. + * + * it will first look in the dir 'type' if no image is found + * it will drop back a dir + * @param type is one of: none, apm, cal, clock, fs, + * host, mail, mem, swap, timer, uptime + */ + QString meterPixmap(int type, bool useDefault = true) const; + /** + * @return the meter image (bg_panel.[png|jpg|gif]) + * of the current theme, it will first look in the dir 'type' + * if no image is found it will drop back a dir + * @param type is one of: net, inet + */ + QString panelPixmap(int type, bool useDefault = true) const; + /** + * @return the decal net leds image + * (usually decal_net_leds.[png|jpg|gif]) of the + * current theme, it will first look in the dir 'type' + * if no image is found it will drop back a dir + * @param type is one of: net, inet + */ + QString ledPixmap(int type, bool useDefault = true) const; + /** + * @return the frame image of the current theme, + * @param type is one of: top, bottom, left, right + */ + QString framePixmap(int type, bool useDefault = true) const; + /** + * @return the krell chart image (bg_chart.[png|jpg|gif]) + * of the current theme + */ + QString chartPixmap(bool useDefault = true) const; + /** + * @return the krell grid image (bg_grid.[png|jpg|gif]) + * of the current theme + */ + QString gridPixmap(bool useDefault = true) const; + /** + * @return the krell panel image (krell_panel.[png|jpg|gif]) + * of the current theme + */ + QString krellPanelPixmap(bool useDefault = true) const; + /** + * @return the krell meter image (krell_meter.[png|jpg|gif]) + * of the current theme + */ + QString krellMeterPixmap(bool useDefault = true) const; + /** + * @return the krell slider image (krell_slider.[png|jpg|gif]) + * of the current theme + */ + QString krellSliderPixmap(bool useDefault = true) const; + /** + * @return the data in image (data_in.[png|jpg|gif]) + * of the current theme + */ + QString dataInPixmap(bool useDefault = true) const; + /** + * @return the data out image (data_out.[png|jpg|gif]) + * of the current theme + */ + QString dataOutPixmap(bool useDefault = true) const; + /** + * @return the mail image (mail/decal_mail.[png|jpg|gif]) + * of the current theme + */ + QString mailPixmap(bool useDefault = true) const; + /** + * @return a segmant of an image, using @p itemNo to + * get the segmant and from the ImageType @p type + */ + QPixmap splitPixmap(PixmapType type, uint itemNo = 0, + bool useDefault = true) const; + /** + * Same as the above function but returns an array of pixmaps + * with the maximum size of limitAmount, or all the pixmaps if @p + * limitAmount is -1 (default) + * @return an array of pixmaps + */ + QValueList<QPixmap> pixmapToList(PixmapType type, + int limitAmount = -1, bool useDefault = true) const; + /** + * returns the transparency level from the specified keys + */ + int transparency(const QString &, const QString &) const; + /** + * @return true if shadow text is enabled + */ + bool textShadow(const QString &, const QString &) const; + /** + * @return the shadow color (if any) for the specified keys + */ + QColor shadowColour(const QString &, const QString &) const; + /** + * @return the text color for the specified keys + */ + QColor textColour(const QString &, const QString &) const; + /** + * reads an entry and returns it as an int + */ + int readIntEntry(const QString &, const QString &) const; + /** + * @return a rect from the specified keys + */ + QRect readRectEntry(const QString &, const QString &) const; + /** + * reads an entry from the specified keys + */ + QString readEntry(const QString &, const QString &) const; + /** + * reads a color entry from the specified keys + */ + QString readColourEntry(const QString &, const QString &, int) const; + /** + * reads a font entry from the specified keys + */ + QFont readFontEntry(const QString &, const QString &) const; + /** + * sets the font, textColour, shadowColour and showShadow to + * the fonts and colours KSim should use depending on type and + * string. + * + * returns true if one of the parameters were changed using + * type and string, else the parameters will be set to the current + * colours and font that KSim should use and returns false. + * + * example usage: + * <pre> + * QFont font; + * QColor textColour, shadowColour; + * bool showShadow; + * if (KSim::ThemeLoader::self().current().fontColours(type(), configString(), font, + * textColour, shadowColour, showShadow) + * { + * setFont(font); + * // Do something with textColour, shadowColour and showShadow + * } + * </pre> + * @param type is the theme type you want, generally if you're calling this + * from a KSim::Base (or derived from) object then use type() + * @param string is the config string entry you want the function to read + * from, generally if you're calling this from a KSim::Base (or derived from) + * object then use configString() + */ + bool fontColours(int type, const QString &string, QFont &font, + QColor &textColour, QColor &shadowColour, bool &showShadow) const; + /** + * convenience function. + * + * collects the theme type and config key from the base pointer + */ + bool fontColours(const KSim::Base *const base, QFont &font, + QColor &textColour, QColor &shadowColour, bool &showShadow) const; + + Theme(const KSim::Theme &); + + private: + Theme(); + Theme(const QString &url, const QString &fileName, int alt, + const QValueVector<QString> &vector, const QStringList &list, + KConfig *globalReader); + void create(const QValueVector<QString> &, const QStringList &, KConfig *); + void init(const QString &url, const QString &fileName, int alt); + void reparse(const QString &url, const QString &fileName, int alt); + QString parseConfig(const QString &, const QString &); + QString loader(int, bool useDefault = true) const; + QString createType(int, const QString &) const; + void setRecolour(bool); + + int internalNumEntry(const QString &, int) const; + QRect internalRectEntry(const QString &, const QRect &) const; + QColor internalColourEntry(const QString &, const QColor &) const; + QString internalStringEntry(const QString &, const QString &) const; + + class Private; + Private *d; + }; + + /** + * returns a class Theme containing + * information of the current theme or + * of the theme path specified + * @author Robbie Ward <linuxphreak@gmx.co.uk> + * @short Provides a loader for the themes + */ + class KDE_EXPORT ThemeLoader + { + public: + /** + * @return a reference to the instance + */ + static ThemeLoader &self(); + /** + * @return true if the theme has changed + */ + bool isDifferent() const; + /** + * Updates the info to the current theme + */ + void reload(); + /** + * @return the current theme that is set + */ + const KSim::Theme ¤t() const; + /** + * @return a theme from the path specified + * @param url is the path of the theme dir + * @param rcFile is the filename of the config file (optional) + * @param alt is the theme alternative number (optional) + */ + KSim::Theme theme(const QString &url, + const QString &rcFile = "gkrellmrc", int alt = 0) const; + /** + * re-colours an image to the current KDE + * color scheme + */ + void reColourImage(QImage &image); + /** + * changes some of the entries in the config file so kconfig + * can handle the file better. + * @return the location of the config file + */ + QString parseConfig(const QString &url, const QString &file); + /** + * change the dir structure of a theme directory + * so KSim can understand them better + */ + void parseDir(const QString &url, int alt); + /** + * checks if the themeUrl entry is valid, + * if not it then reverts the current theme + * to the default url + */ + void validate(); + /** + * sets the pallete of the current theme + */ + void themeColours(QWidget *); + /** + * @return current theme name + */ + static QString currentName(); + /** + * @return current theme url, if there is no current theme + * then it will return the default theme + */ + static QString currentUrl(); + /** + * @return the default theme url + */ + static QString defaultUrl(); + /** + * @return the current theme alternative + */ + static int currentAlternative(); + /** + * @return the current theme alternative as a string, eg if the + * current theme alt is 1 then this will return '_1'. + * if there is no theme alt this will return a null string. + * + * if this is set to -1 (the default) then the current alternative + * will be used + */ + static QString alternativeAsString(int alt = -1); + /** + * @return the font of the theme if the theme font is set to custom + */ + static QFont currentFont(); + /** + * @return the font item of the theme, eg: 0 would be the small font + */ + static int currentFontItem(); + + protected: + /** + * Default constructor, use self() to get an instance + */ + ThemeLoader(); + ~ThemeLoader(); + + private: + ThemeLoader(const ThemeLoader &); + ThemeLoader &operator=(const ThemeLoader &); + /** + * Deletes the instance and cleans up after itself + */ + static void cleanup(); + void reColourItems(); + void grabColour(); + + class Private; + Private *d; + KSim::Theme m_theme; + static ThemeLoader *m_self; + }; +} +#endif diff --git a/ksim/library/themetypes.h b/ksim/library/themetypes.h new file mode 100644 index 0000000..805302c --- /dev/null +++ b/ksim/library/themetypes.h @@ -0,0 +1,81 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#ifndef THEMETYPES_H +#define THEMETYPES_H + +namespace KSim +{ + namespace Types + { + /** + * available types for the frames + */ + enum FrameType + { + TopFrame = 0, + BottomFrame, + LeftFrame, + RightFrame + }; + + /** + * available theme types + */ + enum ThemeType + { + None = -1, + Apm, + Cal, + Clock, + Fs, + Host, + Mail, + Mem, + Swap, + Timer, + Uptime, + Net, + Inet + }; + + /** + * @return the ThemeType enum as a QString + */ + inline QString typeToString(int type, bool incSlash = true) + { + if (type == Types::None) + return QString::null; + + // This array MUST be in the same order + // as the ThemeType enum + const char *typeNames[] = { + "apm", "cal", "clock", + "fs", "host", "mail", + "mem", "swap", "timer", + "uptime", "net", "inet", 0 + }; + + QString returnString; + returnString.setLatin1(typeNames[type]); + return incSlash ? returnString + QString::fromLatin1("/") : returnString; + } + } +} +#endif diff --git a/ksim/monitorprefs.cpp b/ksim/monitorprefs.cpp new file mode 100644 index 0000000..1e67945 --- /dev/null +++ b/ksim/monitorprefs.cpp @@ -0,0 +1,98 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#include "monitorprefs.h" +#include "monitorprefs.moc" + +#include <klocale.h> +#include <kglobal.h> +#include <kdesktopfile.h> +#include <kstandarddirs.h> +#include <kdebug.h> + +#include <ksimconfig.h> +#include <pluginloader.h> + +KSim::MonitorPrefs::MonitorPrefs(QWidget *parent, const char *name) + : KListView(parent, name) +{ + addColumn(i18n("Monitor")); + addColumn(i18n("Description")); + addColumn(i18n("LMB Command")); + + setItemsRenameable(true); + setRenameable(0, false); + setRenameable(2, true); + setDragEnabled(true); + setAcceptDrops(true); + setAllColumnsShowFocus(true); + setSelectionMode(QListView::Single); + + // Scan for .desktop files and enter them into the KListView + m_locatedFiles = KGlobal::dirs()->findAllResources("data", "ksim/monitors/*.desktop"); + m_locatedFiles.sort(); + QStringList::ConstIterator it; + for (it = m_locatedFiles.begin(); it != m_locatedFiles.end(); ++it) { + KDesktopFile file((*it), true); + (void)(new QCheckListItem(this, file.readName(), QCheckListItem::CheckBox))->setText(1, file.readComment()); + } + + sort(); + setSorting(-1, false); +} + +KSim::MonitorPrefs::~MonitorPrefs() +{ +} + +void KSim::MonitorPrefs::saveConfig(KSim::Config *config) +{ + QCheckListItem *item; + QStringList::ConstIterator it; + for (it = m_locatedFiles.begin(); it != m_locatedFiles.end(); ++it) { + KSim::PluginInfo info = KSim::PluginLoader::self().findPluginInfo((*it)); + item = static_cast<QCheckListItem *>(findItem(info.name(), 0)); + config->setEnabledMonitor(info.libName(), item->isOn()); + config->setMonitorCommand(info.libName(), item->text(2)); + config->setMonitorLocation(info.libName(), itemIndex(item)); + } +} + +void KSim::MonitorPrefs::readConfig(KSim::Config *config) +{ + int location; + QCheckListItem *origItem; + QStringList::ConstIterator it; + for (it = m_locatedFiles.begin(); it != m_locatedFiles.end(); ++it) { + KSim::PluginInfo info = KSim::PluginLoader::self().findPluginInfo((*it)); + location = config->monitorLocation(info.libName()); + origItem = static_cast<QCheckListItem *>(findItem(info.name(), 0)); + origItem->setOn(config->enabledMonitor(info.libName())); + origItem->setText(2, config->monitorCommand(info.libName())); + if (QListViewItem *item = itemAtIndex(location)) { + if (location) { + origItem->moveItem(item->itemAbove()); + } + else { + origItem->moveItem(firstChild()); + firstChild()->moveItem(origItem); + } + } + } +} diff --git a/ksim/monitorprefs.h b/ksim/monitorprefs.h new file mode 100644 index 0000000..6cb4798 --- /dev/null +++ b/ksim/monitorprefs.h @@ -0,0 +1,45 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#ifndef MONITORPREFS_H +#define MONITORPREFS_H + +#include <klistview.h> +#include <qstringlist.h> + +namespace KSim +{ + class Config; + + class MonitorPrefs : public KListView + { + Q_OBJECT + public: + MonitorPrefs(QWidget *parent, const char *name=0); + ~MonitorPrefs(); + + public slots: + void saveConfig(KSim::Config *); + void readConfig(KSim::Config *); + + private: + QStringList m_locatedFiles; + }; +} +#endif diff --git a/ksim/monitors/Makefile.am b/ksim/monitors/Makefile.am new file mode 100644 index 0000000..7e5c863 --- /dev/null +++ b/ksim/monitors/Makefile.am @@ -0,0 +1,9 @@ +if supports_i8k +i8k_SUBDIR = i8k +endif + +if include_ksim_monitors_snmp +SNMP_SUBDIR = snmp +endif + +SUBDIRS = filesystem net lm_sensors cpu disk $(i8k_SUBDIR) $(SNMP_SUBDIR) diff --git a/ksim/monitors/cpu/Makefile.am b/ksim/monitors/cpu/Makefile.am new file mode 100644 index 0000000..beaebd2 --- /dev/null +++ b/ksim/monitors/cpu/Makefile.am @@ -0,0 +1,16 @@ +kde_module_LTLIBRARIES = ksim_cpu.la +ksim_cpu_la_SOURCES = ksimcpu.cpp + +ksim_cpu_la_LIBADD = ../../library/libksimcore.la +ksim_cpu_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) + +EXTRA_DIST = cpu.desktop + +INCLUDES= -I$(top_srcdir)/ksim/library \ + $(all_includes) + +METASOURCES = AUTO +KDE_ICON = AUTO + +mon_DATA = cpu.desktop +mondir = $(kde_datadir)/ksim/monitors diff --git a/ksim/monitors/cpu/cpu.desktop b/ksim/monitors/cpu/cpu.desktop new file mode 100644 index 0000000..c8130ec --- /dev/null +++ b/ksim/monitors/cpu/cpu.desktop @@ -0,0 +1,94 @@ +[Desktop Entry] +Icon=ksim_cpu +Name=CPU +Name[af]=Sve +Name[ar]=ÙˆØدة المعالجة المركزية +Name[bg]=ПроцеÑори +Name[cs]=Procesor +Name[el]=KME +Name[eo]=Procezilo +Name[fa]=واØد پردازش مرکزی +Name[fr]=Processeur +Name[he]=מעבד +Name[hi]=सीपीयू +Name[hr]=Procesor +Name[is]=Örgjörvi +Name[kk]=ПроцеÑÑор +Name[mk]=ПроцеÑор +Name[pl]=procesor +Name[ru]=ПроцеÑÑор +Name[sk]=Procesor +Name[sl]=CPE +Name[sv]=Processor +Name[ta]= சிபிய௠+Name[tg]=ВПМ +Name[th]=ซีพียู +Name[tr]=Ä°ÅŸlemci +Name[uk]=ЦП +Name[uz]=Protsessor +Name[uz@cyrillic]=ПроцеÑÑор +Name[wa]=Processeu +Comment=CPU Monitor Plugin +Comment[af]=Sve Monitor Inplak +Comment[ar]=ملØÙ‚ مراقبة ÙˆØدة المعالجة المركزيّة +Comment[bg]=Мониторинг на процеÑора(ите) +Comment[bs]=Dodatak za nadzor CPUa +Comment[ca]=Monitor de CPU +Comment[cs]=Modul pro monitorovánà procesoru +Comment[cy]=Atodyn Monitro CPU +Comment[da]=CPU-overvÃ¥gnings-plugin +Comment[de]=CPU-Nutzungsanzeige +Comment[el]=Î Ïόσθετο εποπτείας KME +Comment[eo]=Prozecilo-observila kromaĵo +Comment[es]=Extensión de monitorización de la CPU +Comment[et]=Protsessori monitooring +Comment[eu]=CPU Plugin Begiralea +Comment[fa]=وصلۀ نمایشگر واØد پردازش مرکزی +Comment[fi]=Suorittimentarkkailusovelma +Comment[fr]=Module de surveillance du processeur +Comment[ga]=Breiseán Monatóireachta LAP +Comment[he]=תוסף צג מעבד +Comment[hi]=सीपीयू मॉनीटर पà¥à¤²à¤—इन +Comment[hu]=CPU-figyelÅ‘ bÅ‘vÃtÅ‘modul +Comment[is]=Örgjörva eftirlitsÃforrit +Comment[it]=Plugin di controllo CPU +Comment[ja]=CPU モニタプラグイン +Comment[ka]= პრáƒáƒªáƒ”სáƒáƒ ის მáƒáƒœáƒ˜áƒ¢áƒáƒ ის მáƒáƒ“ული +Comment[kk]=ПроцеÑÑорды бақылау модулі +Comment[km]=កម្មវិធី​ជំនួយ​នៃ​កម្មវិធី​ážáŸ’ážšáž½ážáž–áž·áž“áž·ážáŸ’យ​ážáž¶ážŸ CPU Monitor +Comment[lt]=CPU stebÄ—tojo priedas +Comment[mk]=Приклучок за Ñледење на процеÑорот +Comment[ms]=Plug masuk Pemerhati CPU +Comment[nb]=Programtillegg for CPU-overvÃ¥kning +Comment[nds]=CPU-Kiekmoduul +Comment[ne]=CPU मोनिटर पà¥à¤²à¤—इन +Comment[nl]=CPU monitor-plugin +Comment[nn]=Programtillegg for CPU-overvaking +Comment[pa]=CPU ਨਿਗਰਾਨੀ ਪਲੱਗਿੰਨ +Comment[pl]=Stan procesora +Comment[pt]='Plugin' de monitorização do processador +Comment[pt_BR]=Plug-in de monitoramento da CPU +Comment[ro]=Modul monitorizare CPU +Comment[ru]=Монитор процеÑÑора +Comment[sk]=Modul pre monitorovanie CPU +Comment[sl]=Vstavek za opazovanje stanja CPE +Comment[sr]=Прикључак за надгледање CPU-а +Comment[sr@Latn]=PrikljuÄak za nadgledanje CPU-a +Comment[sv]=Insticksprogram för processoraktivitet +Comment[ta]= சிபிய௠கணà¯à®•à®¾à®£à®¿ சொரà¯à®•à¯à®ªà¯à®ªà¯Šà®°à¯à®³à¯ +Comment[tg]=Модули Дидабони ВПМ +Comment[th]=ปลั๊à¸à¸à¸´à¸™à¸ªà¸à¸”ส่à¸à¸‡à¸‹à¸µà¸žà¸µà¸¢à¸¹ +Comment[tr]=Ä°ÅŸlemci Ä°zleyici Eklentisi +Comment[uk]=Втулок датчика ЦП +Comment[uz]=Protsessorni nazorat qilish plagini +Comment[uz@cyrillic]=ПроцеÑÑорни назорат қилиш плагини +Comment[wa]=Tchôke-divins di corwaitaedje do CPU +Comment[xh]=Iplagi yangaphakathi ye Monitor CPU +Comment[zh_CN]=CPU 监视器æ’件 +Comment[zh_TW]=CPU ç›£è¦–å™¨å¤–æŽ›ç¨‹å¼ +Comment[zu]=I-plugin Yomlawuli we-CPU +X-KSIM-VERSION=0.1 +X-KSIM-LIBRARY=cpu +X-KSIM-AUTHOR=Robbie Ward +X-KSIM-EMAIL=linuxphreak@gmx.co.uk +X-KSIM-COPYRIGHT=(C) 2001 Robbie Ward diff --git a/ksim/monitors/cpu/cr16-device-ksim_cpu.png b/ksim/monitors/cpu/cr16-device-ksim_cpu.png Binary files differnew file mode 100644 index 0000000..c9d8d08 --- /dev/null +++ b/ksim/monitors/cpu/cr16-device-ksim_cpu.png diff --git a/ksim/monitors/cpu/ksimcpu.cpp b/ksim/monitors/cpu/ksimcpu.cpp new file mode 100644 index 0000000..9e6d089 --- /dev/null +++ b/ksim/monitors/cpu/ksimcpu.cpp @@ -0,0 +1,514 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#include "ksimcpu.h" +#include "ksimcpu.moc" + +#include <qtextstream.h> +#include <qregexp.h> +#include <qlayout.h> +#include <qtimer.h> +#include <qfile.h> +#include <qgroupbox.h> +#include <qlabel.h> +#include <qglobal.h> +#include <qpushbutton.h> + +#include <klistview.h> +#include <kdebug.h> +#include <kaboutapplication.h> +#include <kaboutdata.h> +#include <klocale.h> +#include <kglobal.h> +#include <kconfig.h> +#include <kapplication.h> +#include <kinputdialog.h> + +#include <themetypes.h> + +#ifdef Q_OS_BSD4 +#include <sys/param.h> +#if defined(__DragonFly__) +#include <kinfo.h> +#include <err.h> +#include <sys/time.h> +#include <sys/resource.h> + +#elif defined Q_OS_FREEBSD +#if __FreeBSD_version < 500101 +#include <sys/dkstat.h> +#else +#include <sys/resource.h> +#endif +#else +#include <sys/dkstat.h> +#endif +#include <sys/sysctl.h> +#include <string.h> +#include <kvm.h> +#ifdef Q_OS_NETBSD +#include <sys/sched.h> +#endif +#endif + +#define CPU_NAME(cpu) "Cpu" + QString::number(cpu) + "_options" +#define CPU_SPEED 1000 + +KSIM_INIT_PLUGIN(CpuPlugin) + +CpuPlugin::CpuPlugin(const char *name) + : KSim::PluginObject(name) +{ + setConfigFileName(instanceName()); +} + +CpuPlugin::~CpuPlugin() +{ +} + +KSim::PluginView *CpuPlugin::createView(const char *className) +{ + return new CpuView(this, className); +} + +KSim::PluginPage *CpuPlugin::createConfigPage(const char *className) +{ + return new CpuConfig(this, className); +} + +void CpuPlugin::showAbout() +{ + QString version = kapp->aboutData()->version(); + + KAboutData aboutData(instanceName(), + I18N_NOOP("KSim CPU Plugin"), version.latin1(), + I18N_NOOP("A cpu monitor plugin for KSim"), + KAboutData::License_GPL, "(C) 2001 Robbie Ward"); + + aboutData.addAuthor("Robbie Ward", I18N_NOOP("Author"), + "linuxphreak@gmx.co.uk"); + + KAboutApplication(&aboutData).exec(); +} + +CpuView::CpuView(KSim::PluginObject *parent, const char *name) + : KSim::PluginView(parent, name) +{ +#ifdef Q_OS_LINUX + m_procStream = 0L; + if ((m_procFile = fopen("/proc/stat", "r"))) + m_procStream = new QTextStream(m_procFile, IO_ReadOnly); +#endif + + m_mainLayout = new QVBoxLayout(this); + QSpacerItem *item = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Expanding); + m_mainLayout->addItem(item); + + m_firstTime = true; + + m_cpus = createList(); + addDisplay(); + + m_timer = new QTimer(this); + connect(m_timer, SIGNAL(timeout()), SLOT(updateView())); + m_timer->start(CPU_SPEED); + updateView(); +} + +CpuView::~CpuView() +{ +#ifdef Q_OS_LINUX + delete m_procStream; + + if (m_procFile) + fclose(m_procFile); +#endif + + cleanup(m_cpus); +} + +void CpuView::reparseConfig() +{ + CpuList cpus = createList(); + if (m_cpus != cpus) { + if (m_timer->isActive()) + m_timer->stop(); + + cleanup(m_cpus); + m_cpus = cpus; + addDisplay(); + m_timer->start(CPU_SPEED); + } +} + +void CpuView::updateView() +{ + if (m_cpus.isEmpty()) + return; + + CpuList::Iterator it; + for (it = m_cpus.begin(); it != m_cpus.end(); ++it) { + Cpu ¤t = (*it); + CpuData cpuData; + updateCpu(cpuData, current.number()); + + QString text = current.format(); + current.setData(cpuData); + cpuData -= current.oldData(); + int cpuDiff = 0; + int total = cpuData.sys + cpuData.user + cpuData.nice + cpuData.idle; + +// kdDebug(2003) << "name = " << cpuData.name << endl; +// kdDebug(2003) << "user = " << cpuData.user << endl; +// kdDebug(2003) << "nice = " << cpuData.nice << endl; +// kdDebug(2003) << "sys = " << cpuData.sys << endl; +// kdDebug(2003) << "idle = " << cpuData.idle << endl; + + if (!m_firstTime) { + if (text.find("%T") != -1) + cpuDiff = cpuData.sys + cpuData.user + cpuData.nice; + else if (text.find("%t") != -1) + cpuDiff = cpuData.sys + cpuData.user; + else if (text.find("%s") != -1) + cpuDiff = cpuData.sys; + else if (text.find("%u") != -1) + cpuDiff = cpuData.user; + else if (text.find("%n") != -1) + cpuDiff = cpuData.nice; + + cpuDiff *= 100; + + if ( total > 0 ) + cpuDiff /= total; + + if (cpuDiff > 100) + cpuDiff = 100; + } + + current.chart()->setText(i18n("%1%").arg(cpuDiff)); + current.chart()->setValue(cpuDiff, 0); + current.label()->setValue(cpuDiff); + } + + m_firstTime = false; +} + +void CpuView::updateCpu(CpuData &cpu, int cpuNumber) +{ +#ifdef Q_OS_LINUX + if (!m_procStream) + return; + + bool cpuFound = false; + QString output; + QString parser; + QString cpuString; + cpuString.setNum(cpuNumber).prepend("cpu"); + + // Parse the proc file + while (!m_procStream->atEnd()) { + parser = m_procStream->readLine(); + // remove all the entries apart from the line containing 'cpuString' + if (!cpuFound && parser.find(QRegExp(cpuString)) != -1) { + output = parser; + cpuFound = true; + } + } + + QStringList cpuList = QStringList::split(' ', output); + + if (!cpuList.isEmpty()) { + cpu.name = cpuList[0].stripWhiteSpace(); + cpu.user = cpuList[1].toULong(); + cpu.nice = cpuList[2].toULong(); + cpu.sys = cpuList[3].toULong(); + cpu.idle = cpuList[4].toULong(); + } + + fseek(m_procFile, 0L, SEEK_SET); +#endif + +#ifdef __DragonFly__ + struct kinfo_cputime cp_time; + if (kinfo_get_sched_cputime(&cp_time)) + err(1, "kinfo_get_sched_cputime"); + cpu.user = cp_time.cp_user; + cpu.nice = cp_time.cp_nice; + cpu.sys = cp_time.cp_sys; + cpu.idle = cp_time.cp_idle; +#elif defined(Q_OS_FREEBSD) +#warning "add support for SMP on FreeBSD" + Q_UNUSED(cpuNumber); + static int name2oid[2] = { 0, 3 }; + static int oidCpuTime[CTL_MAXNAME + 2]; + static size_t oidCpuTimeLen = sizeof(oidCpuTime); + long cpuTime[CPUSTATES]; + size_t cpuTimeLen = sizeof(cpuTime); + static char name[] = "kern.cp_time"; + static int initialized = 0; + + if (!initialized) { + if (sysctl(name2oid, 2, oidCpuTime, &oidCpuTimeLen, + name, strlen(name)) < 0) + return; + + oidCpuTimeLen /= sizeof(int); + initialized = 1; + } + + if (sysctl(oidCpuTime, oidCpuTimeLen, + cpuTime, &cpuTimeLen, 0, 0) < 0) + return; + + cpu.user = cpuTime[CP_USER]; + cpu.nice = cpuTime[CP_NICE]; + cpu.sys = cpuTime[CP_SYS]; + cpu.idle = cpuTime[CP_IDLE]; +#endif + +#if defined(Q_OS_NETBSD) +#define KERN_CPTIME KERN_CP_TIME +#endif +#if defined(Q_OS_OPENBSD) || defined(Q_OS_NETBSD) +//#warning "add support for SMP on OpenBSD and NetBSD" + int name2oid[2] = { CTL_KERN, KERN_CPTIME }; + long cpuTime[CPUSTATES]; + size_t cpuTimeLen = sizeof(cpuTime); + + if (sysctl(name2oid, 2, &cpuTime, &cpuTimeLen, + 0, 0) < 0) + return; + + cpu.user = cpuTime[CP_USER]; + cpu.nice = cpuTime[CP_NICE]; + cpu.sys = cpuTime[CP_SYS]; + cpu.idle = cpuTime[CP_IDLE]; +#endif +} + +CpuView::CpuList CpuView::createList() +{ + config()->setGroup("CpuPlugin"); + CpuList list; + + int number = 0; + QStringList cpus = config()->readListEntry("Cpus"); + QStringList::ConstIterator it; + for (it = cpus.begin(); it != cpus.end(); ++it) { + list.append(Cpu((*it), config()->readEntry(CPU_NAME(number), + "%T"), number)); + + ++number; + } + + return list; +} + +void CpuView::addDisplay() +{ + CpuList::Iterator it; + for (it = m_cpus.begin(); it != m_cpus.end(); ++it) { + KSim::Progress *progress = addLabel(); + KSim::Chart *chart = addChart(); + //KSim::Progress *progress = addLabel(); + + (*it).setDisplay(chart, progress); + } +} + +void CpuView::cleanup(CpuList &list) +{ + CpuList::Iterator it; + for (it = list.begin(); it != list.end(); ++it) + (*it).cleanup(); + + list.clear(); +} + +KSim::Chart *CpuView::addChart() +{ + KSim::Chart *chart = new KSim::Chart(false, 0, this); + chart->show(); + m_mainLayout->addWidget(chart); + + return chart; +} + +KSim::Progress *CpuView::addLabel() +{ + KSim::Progress *progress = new KSim::Progress(100, + KSim::Types::None, KSim::Progress::Panel, this); + + progress->show(); + m_mainLayout->addWidget(progress); + + return progress; +} + +CpuConfig::CpuConfig(KSim::PluginObject *parent, const char *name) + : KSim::PluginPage(parent, name) +{ + QVBoxLayout * mainLayout = new QVBoxLayout( this ); + mainLayout->setSpacing( 6 ); + + m_listView = new KListView(this); + m_listView->addColumn(i18n("Available CPUs")); + m_listView->addColumn(i18n("Chart Format")); + m_listView->setAllColumnsShowFocus(true); + m_listView->setSelectionMode(QListView::Single); + connect( m_listView, SIGNAL( doubleClicked( QListViewItem * ) ), + SLOT( modify( QListViewItem * ) ) ); + + mainLayout->addWidget( m_listView ); + + QHBoxLayout * layout = new QHBoxLayout; + layout->setSpacing( 6 ); + + QSpacerItem * spacer = new QSpacerItem( 20, 20, + QSizePolicy::Expanding, QSizePolicy::Minimum ); + layout->addItem(spacer); + + m_modify = new QPushButton( this ); + m_modify->setText( i18n( "Modify..." ) ); + connect( m_modify, SIGNAL( clicked() ), SLOT( modify() ) ); + layout->addWidget( m_modify ); + mainLayout->addLayout( layout ); + + m_legendBox = new QGroupBox(this); + m_legendBox->setColumnLayout(0, Qt::Vertical); + m_legendBox->setTitle(i18n("Chart Legend")); + m_legendBox->layout()->setSpacing(0); + m_legendBox->layout()->setMargin(0); + + m_legendLayout = new QVBoxLayout(m_legendBox->layout()); + m_legendLayout->setAlignment(Qt::AlignTop); + m_legendLayout->setSpacing(6); + m_legendLayout->setMargin(11); + + m_totalNiceLabel = new QLabel(i18n("%T - Total CPU time (sys + user + nice)"), m_legendBox); + m_legendLayout->addWidget(m_totalNiceLabel); + + m_totalLabel = new QLabel(i18n("%t - Total CPU time (sys + user)"), m_legendBox); + m_legendLayout->addWidget(m_totalLabel); + + m_sysLabel = new QLabel(i18n("%s - Total sys time"), m_legendBox); + m_legendLayout->addWidget(m_sysLabel); + + m_userLabel = new QLabel(i18n("%u - Total user time"), m_legendBox); + m_legendLayout->addWidget(m_userLabel); + + m_niceLabel = new QLabel(i18n("%n - Total nice time"), m_legendBox); + m_legendLayout->addWidget(m_niceLabel); + + mainLayout->addWidget( m_legendBox ); + + for (uint i = 0; i < addCpus(); ++i) + { + QCheckListItem *item = new QCheckListItem(m_listView, i18n("cpu %1").arg(i), QCheckListItem::CheckBox); + item->setText(1, "%T"); + } +} + +CpuConfig::~CpuConfig() +{ +} + +void CpuConfig::readConfig() +{ + config()->setGroup("CpuPlugin"); + QStringList enabledCpus(config()->readListEntry("Cpus")); + + int cpuNum = 0; + QStringList::ConstIterator it; + for (it = enabledCpus.begin(); it != enabledCpus.end(); ++it) { + if (QCheckListItem *item = + static_cast<QCheckListItem *>(m_listView->findItem((*it), 0))) { + item->setOn(true); + item->setText(1, config()->readEntry(CPU_NAME(cpuNum), "%T")); + } + ++cpuNum; + } +} + +void CpuConfig::saveConfig() +{ + config()->setGroup("CpuPlugin"); + + int cpuNum = 0; + QStringList enabledCpus; + for (QListViewItemIterator it(m_listView); it.current(); ++it) { + config()->writeEntry(CPU_NAME(cpuNum), it.current()->text(1)); + if (static_cast<QCheckListItem *>(it.current())->isOn()) + enabledCpus.append(it.current()->text(0)); + ++cpuNum; + } + + config()->writeEntry("Cpus", enabledCpus); +} + +uint CpuConfig::addCpus() +{ +#ifdef Q_OS_LINUX + QStringList output; + QString parser; + QFile file("/proc/stat"); + if (!file.open(IO_ReadOnly)) + return 0; + + // Parse the proc file + QTextStream procStream(&file); + while (!procStream.atEnd()) { + parser = procStream.readLine(); + if (QRegExp("cpu").search(parser, 0) != -1 + && QRegExp("cpu0").search(parser, 0) == -1) { + output.append(parser); + } + } + + return output.count(); +#endif + +#ifdef Q_OS_BSD4 + int mib[] = { CTL_HW, HW_NCPU }; // hw.ncpu + uint cpu; + size_t cpuLen = sizeof(cpu); + if (sysctl(mib, 2, &cpu, &cpuLen, NULL, 0) < 0) + return 0; + + return cpu; +#endif +} + +void CpuConfig::modify( QListViewItem * item ) +{ + if ( !item ) + return; + + bool ok = false; + QString text = KInputDialog::getText( i18n( "Modify CPU Format" ), i18n( "Chart format:" ), + item->text( 1 ), &ok, this ); + + if ( ok ) + item->setText( 1, text ); +} + +void CpuConfig::modify() +{ + modify( m_listView->selectedItem() ); +} diff --git a/ksim/monitors/cpu/ksimcpu.h b/ksim/monitors/cpu/ksimcpu.h new file mode 100644 index 0000000..b129ec0 --- /dev/null +++ b/ksim/monitors/cpu/ksimcpu.h @@ -0,0 +1,228 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#ifndef KSIMCPU_H +#define KSIMCPU_H + +#include <pluginmodule.h> +#include <chart.h> +#include <progress.h> + +#include <stdio.h> + +class QPushButton; +class QTextStream; +class QVBoxLayout; +class QHBoxLayout; +class QCheckBox; +class QLabel; +class QGroupBox; +class QTimer; +class QListViewItem; +class KListView; + +class CpuPlugin : public KSim::PluginObject +{ + public: + CpuPlugin(const char *name); + ~CpuPlugin(); + + virtual KSim::PluginView *createView(const char *); + virtual KSim::PluginPage *createConfigPage(const char *); + + virtual void showAbout(); +}; + +class CpuView : public KSim::PluginView +{ + Q_OBJECT + public: + CpuView(KSim::PluginObject *parent, const char *name); + ~CpuView(); + + virtual void reparseConfig(); + + private slots: + void updateView(); + + private: + class CpuData + { + public: + CpuData() { user = nice = sys = idle = 0; } + + QString name; + unsigned long user; + unsigned long nice; + unsigned long sys; + unsigned long idle; + + CpuData &operator-=(const CpuData &rhs) + { + if (name != rhs.name) + return *this; + + user -= rhs.user; + nice -= rhs.nice; + sys -= rhs.sys; + idle -= rhs.idle; + return *this; + } + }; + + class Cpu + { + public: + Cpu() + { + m_num = 0; + m_chart = 0; + m_label = 0; + } + + Cpu(const QString &name, + const QString &format, + int number) + : m_name(name), + m_format(format), + m_num(number) + { + m_chart = 0; + m_label = 0; + } + + ~Cpu() + { + } + + bool operator==(const Cpu &rhs) const + { + return m_name == rhs.m_name && + m_format == rhs.m_format; + } + + bool operator!=(const Cpu &rhs) const + { + return !operator==(rhs); + } + + void cleanup() + { + delete m_chart; + delete m_label; + } + + void setData(const CpuData &data) + { + m_old = m_data; + m_data = data; + } + + const CpuData &oldData() const + { + return m_old; + } + + const QString &format() const + { + return m_format; + } + + int number() const + { + return m_num; + } + + void setDisplay(KSim::Chart *chart, KSim::Progress *label) + { + m_chart = chart; + m_label = label; + m_label->setText(m_name); + } + + KSim::Chart *chart() + { + return m_chart; + } + + KSim::Progress *label() + { + return m_label; + } + + private: + CpuData m_data; + CpuData m_old; + QString m_name; + QString m_format; + KSim::Chart *m_chart; + KSim::Progress *m_label; + int m_num; + }; + + typedef QValueList<Cpu> CpuList; + void updateCpu(CpuData &cpu, int cpuNumber); + CpuList createList(); + + void addDisplay(); + void cleanup(CpuList &); + + KSim::Chart *addChart(); + KSim::Progress *addLabel(); + + QTimer *m_timer; + QVBoxLayout *m_mainLayout; + bool m_firstTime; + CpuList m_cpus; + +#ifdef __linux__ + FILE *m_procFile; + QTextStream *m_procStream; +#endif +}; + +class CpuConfig : public KSim::PluginPage +{ + Q_OBJECT + public: + CpuConfig(KSim::PluginObject *parent, const char *name); + ~CpuConfig(); + + virtual void saveConfig(); + virtual void readConfig(); + + private slots: + void modify( QListViewItem * ); + void modify(); + + private: + uint addCpus(); + + KListView *m_listView; + QGroupBox *m_legendBox; + QLabel *m_totalNiceLabel; + QLabel *m_totalLabel; + QLabel *m_sysLabel; + QLabel *m_userLabel; + QLabel *m_niceLabel; + QVBoxLayout *m_legendLayout; + + QPushButton * m_modify; +}; +#endif diff --git a/ksim/monitors/disk/Makefile.am b/ksim/monitors/disk/Makefile.am new file mode 100644 index 0000000..ce9f79c --- /dev/null +++ b/ksim/monitors/disk/Makefile.am @@ -0,0 +1,15 @@ +kde_module_LTLIBRARIES = ksim_disk.la +ksim_disk_la_SOURCES = ksimdisk.cpp + +ksim_disk_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +ksim_disk_la_LIBADD = $(LIB_DEVSTAT) ../../library/libksimcore.la + +EXTRA_DIST = disk.desktop + +INCLUDES= -I$(top_srcdir)/ksim/library \ + $(all_includes) + +METASOURCES = AUTO + +mon_DATA = disk.desktop +mondir = $(kde_datadir)/ksim/monitors diff --git a/ksim/monitors/disk/configure.in.in b/ksim/monitors/disk/configure.in.in new file mode 100644 index 0000000..19b0e8f --- /dev/null +++ b/ksim/monitors/disk/configure.in.in @@ -0,0 +1,13 @@ +AC_CHECK_LIB(devstat, selectdevs, +[ + LIB_DEVSTAT="-ldevstat" +], +[ + AC_CHECK_LIB(devstat, devstat_selectdevs, + [ + LIB_DEVSTAT="-ldevstat" + ] + ) +]) + +AC_SUBST(LIB_DEVSTAT) diff --git a/ksim/monitors/disk/disk.desktop b/ksim/monitors/disk/disk.desktop new file mode 100644 index 0000000..f048878 --- /dev/null +++ b/ksim/monitors/disk/disk.desktop @@ -0,0 +1,106 @@ +[Desktop Entry] +Comment=Disk Monitor Plugin +Comment[af]=Disket Monitor Inplak +Comment[ar]=ملØÙ‚ مراقبة القرص +Comment[bg]=Мониторинг на входно-изходите операции Ñ Ð´Ð¸Ñка +Comment[bs]=Dodatak za nadzor diska +Comment[ca]=Monitor de disc +Comment[cs]=Modul pro monitorovánà disku +Comment[cy]=Atodyn Monitro Disg +Comment[da]=DiskovervÃ¥gnings-plugin +Comment[de]=Hilfsprogramm zur Festplattenüberwachung +Comment[el]=Î Ïόσθετο εποπτείας δίσκου +Comment[eo]=Disk-observa kromaĵo +Comment[es]=Extensión de monitorización de disco +Comment[et]=Ketta monitooring +Comment[eu]=Diskoaren Plugin Begiralea +Comment[fa]=وصلۀ نمایشگر دیسک +Comment[fi]=Levyntarkkailusovelma +Comment[fr]=Module de surveillance du disque +Comment[ga]=Breiseán Monatóireachta Diosca +Comment[he]=תוסף צג דיסק +Comment[hi]=डिसà¥à¤• मॉनीटर पà¥à¤²à¤—इन +Comment[hu]=LemezfigyelÅ‘ bÅ‘vÃtÅ‘modul +Comment[is]=Disk eftirlitsforrit +Comment[it]=Plugin di controllo disco +Comment[ja]=ディスクモニタプラグイン +Comment[ka]= დისკის მáƒáƒœáƒ˜áƒ¢áƒáƒ ის მáƒáƒ“ული +Comment[kk]=ДиÑкін бақылау модулі +Comment[km]=កម្មវិធី​ជំនួយ​នៃ​កម្មវិធី​ážáŸ’ážšáž½ážáž–áž·áž“áž·ážáŸ’យ​ážáž¶ážŸ +Comment[lt]=Disko stebÄ—tojo priedas +Comment[mk]=Приклучок за Ñледење на диÑкот +Comment[ms]=Plug masuk Pemerhati Monitor +Comment[nb]=Programtillegg for diskovervÃ¥kning +Comment[nds]=Fastplaat-Kiekmoduul +Comment[ne]=डिसà¥à¤• मोनिटर पà¥à¤²à¤—इन +Comment[nl]=Disk monitor-plugin +Comment[nn]=Programtillegg for diskovervaking +Comment[pa]=ਡਿਸਕ ਨਿਗਰਾਨ ਪਲੱਗਿੰਨ +Comment[pl]=Stan dysku +Comment[pt]='Plugin' de Monitorização do Disco +Comment[pt_BR]=Plug-in de monitoramento do Disco +Comment[ro]=Modul monitorizare disc +Comment[ru]=Монитор диÑкового проÑтранÑтва +Comment[sk]=Modul pre monitorovanie disku +Comment[sl]=Vstavek za opazovanje diska +Comment[sr]=Прикључак за надгледање диÑка +Comment[sr@Latn]=PrikljuÄak za nadgledanje diska +Comment[sv]=Insticksprogram för diskövervakning +Comment[ta]= வடà¯à®Ÿà¯ கணà¯à®•à®¾à®£à®¿ சொரà¯à®•à¯à®ªà¯à®ªà¯Šà®°à¯à®³à¯ +Comment[tg]=Модули Дидабони ДиÑк +Comment[th]=ปลั๊à¸à¸à¸´à¸™à¸•à¸£à¸§à¸ˆà¸à¸²à¸£à¸—ำงานดิสà¸à¹Œ +Comment[tr]=Disk Ä°zleyici Eklentisi +Comment[uk]=Втулок датчика диÑку +Comment[uz]=Diskni nazorat qilish plagini +Comment[uz@cyrillic]=ДиÑкни назорат қилиш плагини +Comment[wa]=Tchôke-divins di corwaitaedje del deure plake +Comment[xh]=Iplagi efakiweyo ye Monitor Yediski +Comment[zh_CN]=ç£ç›˜ç›‘视器æ’件 +Comment[zh_TW]=ç£ç¢Ÿç›£è¦–å™¨å¤–æŽ›ç¨‹å¼ +Comment[zu]=I-plugin Yomlawuli Wediski +Icon=hdd_mount +Name=Disk +Name[af]=Disket +Name[ar]=قرص +Name[bg]=ДиÑкове +Name[br]=Pladenn +Name[ca]=Disc +Name[el]=Δίσκος +Name[eo]=Disko +Name[es]=Disco +Name[et]=Ketas +Name[eu]=Diskoa +Name[fa]=دیسک +Name[fi]=Levy +Name[ga]=Diosca +Name[he]=דיסק +Name[hi]=डिसà¥à¤• +Name[hu]=Lemez +Name[is]=Diskur +Name[it]=Disco +Name[ja]=ディスク +Name[kk]=ДиÑкі +Name[km]=ážáž¶ážŸ +Name[lt]=Diskas +Name[lv]=Disks +Name[mk]=ДиÑк +Name[ms]=Cakera +Name[nds]=Fastplaat +Name[ne]=डिसà¥à¤• +Name[pa]=ਡਿਸਕ +Name[pl]=Dysk +Name[pt]=Disco +Name[pt_BR]=Disco +Name[ro]=Disc +Name[ru]=ДиÑк +Name[sr]=ДиÑк +Name[ta]=வடà¯à®Ÿà¯ +Name[tg]=ДиÑк +Name[th]=ดิสà¸à¹Œ +Name[uk]=ДиÑк +Name[uz@cyrillic]=ДиÑк +Name[wa]=Deure plake +Name[xh]=Idiski +Name[zh_CN]=ç£ç›˜ +Name[zu]=Idiski +X-KSIM-LIBRARY=disk diff --git a/ksim/monitors/disk/ksimdisk.cpp b/ksim/monitors/disk/ksimdisk.cpp new file mode 100644 index 0000000..2fe3560 --- /dev/null +++ b/ksim/monitors/disk/ksimdisk.cpp @@ -0,0 +1,570 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#include "ksimdisk.h" +#include "ksimdisk.moc" + +#include <qtextstream.h> +#include <qregexp.h> +#include <qtimer.h> +#include <qlayout.h> +#include <qradiobutton.h> +#include <qvbuttongroup.h> +#include <qpushbutton.h> + +#include <kdebug.h> +#include <kaboutapplication.h> +#include <kaboutdata.h> +#include <klocale.h> +#include <kapplication.h> +#include <klistview.h> +#include <kinputdialog.h> +#include <kconfig.h> + +#include <chart.h> +#include <progress.h> +#include <themetypes.h> + +#if defined(__DragonFly__) +#include <sys/time.h> +#include <sys/param.h> +#include <sys/resource.h> +#include <devstat.h> +#include <stdlib.h> +#elif defined(Q_OS_FREEBSD) +#include <sys/param.h> +#if __FreeBSD_version < 500101 +#include <sys/dkstat.h> +#else +#include <sys/resource.h> +#endif +#include <devstat.h> +#include <stdlib.h> +#endif + +#ifdef Q_OS_LINUX +#include <linux/major.h> +#endif + +#include <iostream> + +#define DISK_SPEED 1000 + +KSIM_INIT_PLUGIN(DiskPlugin) + +DiskPlugin::DiskPlugin(const char *name) + : KSim::PluginObject(name) +{ + setConfigFileName(instanceName()); +} + +DiskPlugin::~DiskPlugin() +{ +} + +KSim::PluginView *DiskPlugin::createView(const char *className) +{ + return new DiskView(this, className); +} + +KSim::PluginPage *DiskPlugin::createConfigPage(const char *className) +{ + return new DiskConfig(this, className); +} + +void DiskPlugin::showAbout() +{ + QString version = kapp->aboutData()->version(); + + KAboutData aboutData(instanceName(), + I18N_NOOP("KSim Disk Plugin"), version.latin1(), + I18N_NOOP("A disk monitor plugin for KSim"), + KAboutData::License_GPL, "(C) 2001 Robbie Ward"); + + aboutData.addAuthor("Robbie Ward", I18N_NOOP("Author"), + "linuxphreak@gmx.co.uk"); + + KAboutApplication(&aboutData).exec(); +} + +DiskView::DiskView(KSim::PluginObject *parent, const char *name) + : KSim::PluginView(parent, name) +{ +#ifdef Q_OS_LINUX + m_bLinux24 = true; + m_procStream = 0L; + if ((m_procFile = fopen("/proc/stat", "r"))) + m_procStream = new QTextStream(m_procFile, IO_ReadOnly); +#endif + + config()->setGroup("DiskPlugin"); + m_list = config()->readListEntry("Disks", QStringList() << "complete"); + m_useSeperatly = config()->readBoolEntry("UseSeperatly", true); + + m_firstTime = 1; + m_addAll = false; + m_layout = new QVBoxLayout(this); + QSpacerItem *item = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Expanding); + m_layout->addItem(item); + + init(); + + m_timer = new QTimer(this); + connect(m_timer, SIGNAL(timeout()), SLOT(updateDisplay())); + m_timer->start(DISK_SPEED); + updateDisplay(); +} + +DiskView::~DiskView() +{ +#ifdef Q_OS_LINUX + delete m_procStream; + + if (m_procFile) + fclose(m_procFile); +#endif +} + +void DiskView::reparseConfig() +{ + config()->setGroup("DiskPlugin"); + QStringList list = config()->readListEntry("Disks", QStringList() << "complete"); + m_useSeperatly = config()->readBoolEntry("UseSeperatly", true); + + if (list != m_list) { + m_list = list; + m_timer->stop(); + cleanup(); + + QPtrListIterator<DiskPair> it(m_diskList); + for (; it.current(); ++it) { + delete it.current()->first; + delete it.current()->second; + } + + m_diskList.clear(); + init(); + m_timer->start(DISK_SPEED); + updateDisplay(); + } +} + +DiskView::DiskData DiskView::findDiskData(const DiskList& diskList, QString diskName) +{ + if (diskName == "complete") + diskName = i18n("All Disks"); + + DiskView::DiskList::ConstIterator disk; + for (disk = diskList.begin(); disk != diskList.end(); ++disk) + if ((*disk).name == diskName) + return *disk; + + // Not found + DiskView::DiskData dummy; + dummy.name = "["+diskName+"]"; + return dummy; +} + +// Kind of messy code, dont ya think? +void DiskView::updateDisplay() +{ + DiskList diskList; + + updateData(diskList); + + if (m_addAll) + { + DiskData all; + all.name = i18n("All Disks"); + + for (DiskList::ConstIterator disk = diskList.begin(); + disk != diskList.end(); ++disk) + { + all += (*disk); + } + + diskList.prepend(all); + } + + // merge all the disks into one + QPtrListIterator<DiskPair> it(m_diskList); + for (int i = 0; it.current(); ++it, ++i) { + DiskData diskData = findDiskData(diskList, m_list[i]); + m_data[i].second = m_data[i].first; + m_data[i].first = diskData; + diskData -= m_data[i].second; + unsigned long diff = diskData.readBlocks + diskData.writeBlocks; + if (m_firstTime) + diff = diskData.readBlocks = diskData.writeBlocks = 0; + + if (m_useSeperatly) { + it.current()->first->setValue(diskData.readBlocks, diskData.writeBlocks); + it.current()->first->setText(i18n("in: %1k") + .arg(KGlobal::locale()->formatNumber((float)diskData.readBlocks / 1024.0, 1)), + i18n("out: %1k").arg(KGlobal::locale()->formatNumber((float)diskData.writeBlocks / 1024.0, 1))); + } + else { + it.current()->first->setValue(diff, 0); + it.current()->first->setText(i18n("%1k") + .arg(KGlobal::locale()->formatNumber((float)diff / 1024.0, 1))); + } + + it.current()->second->setMaxValue(it.current()->first->maxValue()); + it.current()->second->setText(diskData.name); + it.current()->second->setValue(diff); + } + + m_firstTime = 0; +} + +void DiskView::updateData(DiskList &disks) +{ +#ifdef Q_OS_LINUX + if (!m_procStream) + return; + + m_procStream->device()->reset(); + fseek(m_procFile, 0L, SEEK_SET); + + if (m_bLinux24) + { + // here we need a regexp to match something like: + // (3,0):(108911,48080,1713380,60831,1102644) + QRegExp regexp("\\([0-9]+,[0-9]+\\):\\([0-9]+,[0-9]+,[0-9]+,[0-9]+,[0-9]+\\)"); + QString content = m_procStream->read(); + if (content.find("disk_io") == -1) + { + m_bLinux24 = false; + + delete m_procStream; + m_procStream = 0; + fclose(m_procFile); + + if ((m_procFile = fopen("/proc/diskstats", "r"))) + m_procStream = new QTextStream(m_procFile, IO_ReadOnly); + + updateData(disks); + return; + } + int idx = 0; + while ((idx = regexp.search(content, idx)) != -1) + { + idx += regexp.matchedLength(); + QString diskStr = regexp.cap(0); + diskStr.replace(':', ','); + diskStr.replace(QRegExp("\\)?\\(?"), QString::null); + + QStringList list = QStringList::split(',', diskStr); + if (list.count() < 7) + continue; + + DiskData diskData; + diskData.major = list[0].toInt(); + diskData.minor = list[1].toInt(); + diskData.name = diskName( diskData.major, diskData.minor ); + diskData.total = list[2].toULong(); + diskData.readIO = list[3].toULong(); + diskData.readBlocks = list[4].toULong(); + diskData.writeIO = list[5].toULong(); + diskData.writeBlocks = list[6].toULong(); + disks.append(diskData); + } + } + else + { + // 3 0 hda 564142 160009 14123957 12369403 1052983 2801992 30905928 78981451 0 4531584 91518334 + // The 11 fields after the device name are defined as follows: + // Field 1 -- # of reads issued + // This is the total number of reads completed successfully. + // Field 2 -- # of reads merged, + // Reads and writes which are adjacent to each other may be merged for + // efficiency. Thus two 4K reads may become one 8K read before it is + // ultimately handed to the disk, and so it will be counted (and queued) + // as only one I/O. This field lets you know how often this was done. + // Field 3 -- # of sectors read + // This is the total number of sectors read successfully. + // Field 4 -- # of milliseconds spent reading + // This is the total number of milliseconds spent by all reads (as + // measured from __make_request() to end_that_request_last()). + // Field 5 -- # of writes completed + // This is the total number of writes completed successfully. + // Field 6 -- # of writes merged + // See field 2 + // Field 7 -- # of sectors written + // This is the total number of sectors written successfully. + // Field 8 -- # of milliseconds spent writing + // This is the total number of milliseconds spent by all writes (as + // measured from __make_request() to end_that_request_last()). + // Field 9 -- # of I/Os currently in progress + // The only field that should go to zero. Incremented as requests are + // given to appropriate request_queue_t and decremented as they finish. + // Field 10 -- # of milliseconds spent doing I/Os + // This field is increases so long as field 9 is nonzero. + // Field 11 -- weighted # of milliseconds spent doing I/Os + // This field is incremented at each I/O start, I/O completion, I/O + // merge, or read of these stats by the number of I/Os in progress + // (field 9) times the number of milliseconds spent doing I/O since the + // last update of this field. This can provide an easy measure of both + // I/O completion time and the backlog that may be accumulating. + QString content = m_procStream->read(); + QStringList lines = QStringList::split('\n', content); + + for(QStringList::ConstIterator it = lines.begin(); + it != lines.end(); ++it) + { + QString diskStr = (*it).simplifyWhiteSpace(); + QStringList list = QStringList::split(' ', diskStr); + if (list.count() < 14) + continue; + + DiskData diskData; + diskData.major = list[0].toInt(); + diskData.minor = list[1].toInt(); + diskData.name = list[2]; + diskData.readIO = 0; + diskData.readBlocks = list[3+2].toULong(); + diskData.writeIO = 0; + diskData.writeBlocks = list[7+2].toULong(); + diskData.total = diskData.readBlocks + diskData.writeBlocks; + disks.append(diskData); + } + } + +#endif + +#ifdef Q_OS_FREEBSD +#if defined(__DragonFly__) || __FreeBSD_version < 500107 +#define devstat_getdevs(fd, stats) getdevs(stats) +#define devstat_selectdevs selectdevs +#define bytes_read(dev) (dev).bytes_read +#define bytes_written(dev) (dev).bytes_written +#else +#define bytes_read(dev) (dev).bytes[DEVSTAT_READ] +#define bytes_written(dev) (dev).bytes[DEVSTAT_WRITE] +#endif + + statinfo diskStats; + bzero(&diskStats, sizeof(diskStats)); + diskStats.dinfo = (struct devinfo *)malloc(sizeof(struct devinfo)); + bzero(diskStats.dinfo, sizeof(struct devinfo)); + int deviceAmount; + int selected; + int selections; + long generation; + device_selection *deviceSelect = 0; + + if (devstat_getdevs(NULL, &diskStats) < 0) + return; + + deviceAmount = diskStats.dinfo->numdevs; + if (devstat_selectdevs(&deviceSelect, &selected, &selections, + &generation, diskStats.dinfo->generation, + diskStats.dinfo->devices, deviceAmount, + 0, 0, 0, 0, DS_SELECT_ONLY, 10, 1) < 0) + return; + + unsigned long readBlocks = 0, writeBlocks = 0, blockSize; + for (int i = 0; i < deviceAmount; ++i) { + int disk; + devstat device; + disk = deviceSelect[i].position; + device = diskStats.dinfo->devices[disk]; + blockSize = (device.block_size <= 0 ? 512 : device.block_size); + readBlocks = bytes_read(device) / blockSize; + writeBlocks = bytes_written(device) / blockSize; + + DiskData diskData; + diskData.name = device.device_name + + QString::number(device.unit_number); + diskData.major = device.device_number; + diskData.minor = 0; + diskData.total = readBlocks + writeBlocks; + diskData.readIO = 0; + diskData.readBlocks = readBlocks; + diskData.writeIO = 0; + diskData.writeBlocks = writeBlocks; + disks.append(diskData); + } + + free(deviceSelect); + free(diskStats.dinfo); +#endif +} + +QString DiskView::diskName( int major, int minor ) const +{ +#ifdef Q_OS_LINUX + QString returnValue; + switch ( major ) + { + case IDE0_MAJOR: + returnValue.prepend(QString::fromLatin1("hda")); + break; + case IDE1_MAJOR: + returnValue.prepend(QString::fromLatin1("hdc")); + break; + case IDE3_MAJOR: + returnValue.prepend(QString::fromLatin1("hde")); + break; + case SCSI_DISK0_MAJOR: + returnValue.prepend(QString::fromLatin1("sda")); + break; + case SCSI_GENERIC_MAJOR: + returnValue.prepend(QString::fromLatin1("sg0")); + break; + } + + returnValue.at(2) = returnValue.at(2).latin1() + minor; + return returnValue; +#else + Q_UNUSED(major); + Q_UNUSED(minor); + return 0; +#endif +} + +DiskView::DiskPair *DiskView::addDisk() +{ + KSim::Chart *chart = new KSim::Chart(false, 0, this); + chart->show(); + m_layout->addWidget(chart); + + KSim::Progress *progress = new KSim::Progress(0, KSim::Types::None, + KSim::Progress::Panel, this); + progress->show(); + m_layout->addWidget(progress); + + return new DiskPair(chart, progress); +} + +void DiskView::init() +{ + m_data.resize(m_list.size()); + + QStringList::ConstIterator it; + for (it = m_list.begin(); it != m_list.end(); ++it) { + if ((*it) == "complete") + m_addAll = true; + + m_diskList.append(addDisk()); + } +} + +void DiskView::cleanup() +{ + m_data.clear(); + m_addAll = false; +} + +DiskConfig::DiskConfig(KSim::PluginObject *parent, const char *name) + : KSim::PluginPage(parent, name) +{ + m_layout = new QVBoxLayout(this); + m_layout->setSpacing(6); + + m_listview = new KListView(this); + m_listview->addColumn(i18n("Disks")); + m_layout->addWidget(m_listview); + + QHBoxLayout *layout = new QHBoxLayout; + layout->setSpacing(6); + + QSpacerItem *spacer = new QSpacerItem(20, 20, + QSizePolicy::Expanding, QSizePolicy::Minimum); + layout->addItem(spacer); + + m_add = new QPushButton(this); + m_add->setText(i18n("Add...")); + connect(m_add, SIGNAL(clicked()), SLOT(addItem())); + layout->addWidget(m_add); + + m_remove = new QPushButton(this); + m_remove->setText(i18n("Remove")); + connect(m_remove, SIGNAL(clicked()), SLOT(removeItem())); + layout->addWidget(m_remove); + m_layout->addLayout(layout); + + m_buttonBox = new QVButtonGroup(i18n("Disk Styles"), this); + m_layout->addWidget(m_buttonBox); + + m_totalButton = new QRadioButton(m_buttonBox); + m_totalButton->setText(i18n("Display the read and write data as one")); + m_bothButton = new QRadioButton(m_buttonBox); + m_bothButton->setText(i18n("Display the read and write data" + "\nseparately as in/out data")); + + QSpacerItem *vSpacer = new QSpacerItem(20, 20, + QSizePolicy::Minimum, QSizePolicy::Expanding); + m_layout->addItem(vSpacer); +} + +DiskConfig::~DiskConfig() +{ +} + +void DiskConfig::readConfig() +{ + config()->setGroup("DiskPlugin"); + m_buttonBox->setButton(config()->readBoolEntry("UseSeperatly", true)); + QStringList list = config()->readListEntry("Disks"); + + QStringList::ConstIterator it; + for (it = list.begin(); it != list.end(); ++it) { + QString text = ((*it) == "complete" ? i18n("All Disks") : (*it)); + if (!m_listview->findItem(text, 0)) + new QListViewItem(m_listview, text); + } +} + +void DiskConfig::saveConfig() +{ + QStringList list; + for (QListViewItemIterator it(m_listview); it.current(); ++it) { + if (it.current()->text(0) == i18n("All Disks")) + list.append("complete"); + else + list.append(it.current()->text(0)); + } + + config()->setGroup("DiskPlugin"); + config()->writeEntry("UseSeperatly", (bool)m_buttonBox->id(m_buttonBox->selected())); + config()->writeEntry("Disks", list); +} + +void DiskConfig::addItem() +{ + bool ok = false; + QString text = KInputDialog::getText(i18n("Add Disk Device"), i18n("Disk name:"), + QString::null, &ok, this); + + if (text.startsWith("/dev/")) + text = text.mid(5); + + if (ok) + new QListViewItem(m_listview, text); +} + +void DiskConfig::removeItem() +{ + if (!m_listview->selectedItem()) + return; + + QListViewItem *item = m_listview->selectedItem(); + delete item; +} diff --git a/ksim/monitors/disk/ksimdisk.h b/ksim/monitors/disk/ksimdisk.h new file mode 100644 index 0000000..de4c8ba --- /dev/null +++ b/ksim/monitors/disk/ksimdisk.h @@ -0,0 +1,154 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#ifndef KSIMDISK_H +#define KSIMDISK_H + +#include <qvaluelist.h> +#include <pluginmodule.h> +#include <stdio.h> +#include <qptrlist.h> +#include <qstringlist.h> +#include <qvaluevector.h> + +class QTextStream; +class QTimer; +class KListView; +class QVBoxLayout; +class QVButtonGroup; +class QRadioButton; +class QPushButton; +namespace KSim +{ + class Chart; + class Progress; +} + +class DiskPlugin : public KSim::PluginObject +{ + public: + DiskPlugin(const char *name); + ~DiskPlugin(); + + virtual KSim::PluginView *createView(const char *); + virtual KSim::PluginPage *createConfigPage(const char *); + + virtual void showAbout(); +}; + +class DiskView : public KSim::PluginView +{ + Q_OBJECT + public: + DiskView(KSim::PluginObject *parent, const char *name); + ~DiskView(); + + virtual void reparseConfig(); + + private slots: + void updateDisplay(); + + private: + class DiskData + { + public: + DiskData() + { + major = minor = readIO = readBlocks = + writeIO = writeBlocks = 0; + } + + DiskData &operator+=(const DiskData &rhs) + { + total += rhs.total; + readIO += rhs.readIO; + readBlocks += rhs.readBlocks; + writeIO += rhs.writeIO; + writeBlocks += rhs.writeBlocks; + return *this; + } + + DiskData &operator-=(const DiskData &rhs) + { + total -= rhs.total; + readIO -= rhs.readIO; + readBlocks -= rhs.readBlocks; + writeIO -= rhs.writeIO; + writeBlocks -= rhs.writeBlocks; + return *this; + } + + QString name; + int major; + int minor; + unsigned long total; + unsigned long readIO; + unsigned long readBlocks; + unsigned long writeIO; + unsigned long writeBlocks; + }; + + typedef QValueList<DiskData> DiskList; + typedef QPair<KSim::Chart *, KSim::Progress *> DiskPair; + + void updateData(DiskList &disks); + QString diskName( int, int ) const; + DiskPair *addDisk(); + DiskData findDiskData(const DiskList& diskList, QString diskName); + + void init(); + void cleanup(); + + QValueVector<QPair<DiskData, DiskData> > m_data; + QTimer *m_timer; + bool m_bLinux24; + FILE *m_procFile; + QTextStream *m_procStream; + QVBoxLayout *m_layout; + QPtrList<DiskPair> m_diskList; + int m_firstTime; + bool m_useSeperatly; + QStringList m_list; + bool m_addAll; +}; + +class DiskConfig : public KSim::PluginPage +{ + Q_OBJECT + public: + DiskConfig(KSim::PluginObject *parent, const char *name); + ~DiskConfig(); + + virtual void saveConfig(); + virtual void readConfig(); + + private slots: + void addItem(); + void removeItem(); + + private: + QVBoxLayout *m_layout; + KListView *m_listview; + QPushButton *m_add; + QPushButton *m_remove; + QVButtonGroup *m_buttonBox; + QRadioButton *m_totalButton; + QRadioButton *m_bothButton; +}; +#endif diff --git a/ksim/monitors/filesystem/DFree.desktop b/ksim/monitors/filesystem/DFree.desktop new file mode 100644 index 0000000..78ffdb1 --- /dev/null +++ b/ksim/monitors/filesystem/DFree.desktop @@ -0,0 +1,87 @@ +[Desktop Entry] +Icon=hdd_unmount +Name=DFree +Name[af]=Dfree +Name[bg]=ДÑлове +Name[ca]=Disc lliure +Name[cs]=Volný disk +Name[eo]=Diskuzo +Name[et]=Vaba kettaruum +Name[he]=מחיצות +Name[hi]=डी-फà¥à¤°à¥€ +Name[it]=Disco libero +Name[kk]=Тіркеген бөлімдер +Name[ko]=ë””ìŠ¤í¬ ì‚¬ìš©ëŸ‰ +Name[ne]=डिफà¥à¤°à¤¿ +Name[pt_BR]=Disco Livre +Name[ru]=Смонтированные разделы +Name[sk]=Voľný disk +Name[sv]=Ledigt diskutrymme +Name[ta]= Dபிரீ +Name[tg]=DОзод +Name[th]=พื้นที่ว่างขà¸à¸‡à¸”ิสà¸à¹Œ +Comment=Mounted Partitions Monitor +Comment[af]=Gekoppelde Partisies Monitor +Comment[ar]=مراقب الأقسام المضمومة +Comment[bg]=Мониторинг на монтираните дÑлове +Comment[bs]=Nadzor montiranih particija +Comment[ca]=Monitor de les particions muntades +Comment[cs]=Monitor pÅ™ipojených diskových oddÃlů +Comment[cy]=Monitr Rhaniadau Mowntiedig +Comment[da]=OvervÃ¥gning af monterede partitioner +Comment[de]=Anzeige für eingebundene Laufwerke +Comment[el]=Επόπτης Ï€ÏοσαÏτημÎνων κατατμήσεων +Comment[eo]=Vidigilo por la kroĉitaj subdiskoj +Comment[es]=Monitor de particiones montadas +Comment[et]=Ãœhendatud partitsioonide monitooring +Comment[eu]=Muntatutako Partizioen Begiralea +Comment[fa]=نمایشگر اÙرازهای سوارشده +Comment[fi]=Liitettyjen osioiden valvonta +Comment[fr]=Surveillant des lecteurs montés +Comment[ga]=Monatóir Rannta Feistithe +Comment[he]=צג מחיצות מחוברות +Comment[hi]=माउनà¥à¤Ÿà¥‡à¤¡ पारà¥à¤Ÿà¥€à¤¶à¤¨à¥à¤¸ मॉनीटर +Comment[hu]=Lemezcsatlakoztatás-figyelÅ‘ +Comment[is]=Eftirlit með tengdum disksneiðum +Comment[it]=Controllo delle partizioni montate +Comment[ja]=マウントã•ã‚ŒãŸãƒ‘ーティションã®ãƒ¢ãƒ‹ã‚¿ +Comment[ka]= მáƒáƒœáƒ¢áƒ˜áƒ ებული პáƒáƒ ტიციების მáƒáƒœáƒ˜áƒ¢áƒáƒ ი +Comment[kk]=Тіркеген бөлімдерді бақылау +Comment[km]=កម្មវិធី​ážáŸ’ážšáž½ážáž–áž·áž“áž·ážáŸ’យ​ភាគ​ដែល​បាន​ម៉ោន +Comment[lt]=Sumontuotų skirsnių stebÄ—tojas +Comment[mk]=Монитор на монтираните партиции +Comment[ms]=Pemerhati Partisi yang telah Dilekapkan +Comment[nb]=OvervÃ¥kning av monterte partisjoner +Comment[nds]=Kieker för inhangte Partitschonen +Comment[ne]=माउनà¥à¤Ÿ गरिà¤à¤•à¥‹ विà¤à¤¾à¤œà¤¨ मोनिटर +Comment[nl]=Monitor van aangekoppelde partities +Comment[nn]=Overvaking av monterte partisjonar +Comment[pa]=ਮਾਊਂਟ à¨à¨¾à¨— ਨਿਗਰਾਨ +Comment[pl]=Stan zamontowanych partycji +Comment[pt]=Monitor de Partições Montadas +Comment[pt_BR]=Monitor das Partições Montadas +Comment[ro]=Monitor partiÅ£ii montate +Comment[ru]=Монитор Ñмонтированных разделов +Comment[sk]=Monitor pripojených diskových oddielov +Comment[sl]=Nadzornik priklopljenih razdelkov +Comment[sr]=Ðадгледање монтираних партиција +Comment[sr@Latn]=Nadgledanje montiranih particija +Comment[sv]=Övervakar monterade partitioner +Comment[ta]=à®à®±à¯à®±à®ªà¯à®ªà®Ÿà¯à®Ÿ பகà¯à®•à¯à®•à®ªà¯à®ªà®Ÿà¯à®Ÿ கணà¯à®•à®¾à®£à®¿ +Comment[tg]=Дидабони ҚиÑмҳои ÐаÑбшуда +Comment[th]=สà¸à¸”ส่à¸à¸‡à¸žà¸²à¸£à¹Œà¸•à¸´à¸Šà¸±à¸™à¸—ี่เมานท์ไว้à¹à¸¥à¹‰à¸§ +Comment[tr]=BaÄŸlanmış Disk Bölümü Ä°zleyici +Comment[uk]=Монітор змонтованих розділів +Comment[uz]=Diskning ulangan qismlarini nazorat qilish plagini +Comment[uz@cyrillic]=ДиÑкнинг уланган қиÑмларини назорат қилиш плагини +Comment[wa]=Corwaitoe des montêyès pÃ¥rticions +Comment[xh]=Ulwahlulo Lonyuso lwe Monitor +Comment[zh_CN]=已挂载分区监视器 +Comment[zh_TW]=已掛載的分割å€ç›£è¦–器 +Comment[zu]=Umlawuli Wezahlukaniso Ezinyukile +X-KSIM-VERSION=0.1 +X-KSIM-LIBRARY=filesystem +X-KSIM-PREFS=File System +X-KSIM-AUTHOR=Robbie Ward +X-KSIM-EMAIL=linuxphreak@gmx.co.uk +X-KSIM-COPYRIGHT=(C) 2001 Robbie Ward diff --git a/ksim/monitors/filesystem/Makefile.am b/ksim/monitors/filesystem/Makefile.am new file mode 100644 index 0000000..7da7012 --- /dev/null +++ b/ksim/monitors/filesystem/Makefile.am @@ -0,0 +1,16 @@ +kde_module_LTLIBRARIES = ksim_filesystem.la +ksim_filesystem_la_SOURCES = ksimfsystem.cpp fsystemconfig.cpp \ + fsystemiface.skel filesystemwidget.cpp filesystemstats.cpp + +ksim_filesystem_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +ksim_filesystem_la_LIBADD = ../../library/libksimcore.la + +EXTRA_DIST = DFree.desktop + +INCLUDES= -I$(top_srcdir)/ksim/library \ + $(all_includes) + +METASOURCES = AUTO + +mon_DATA = DFree.desktop +mondir = $(kde_datadir)/ksim/monitors diff --git a/ksim/monitors/filesystem/configure.in.in b/ksim/monitors/filesystem/configure.in.in new file mode 100644 index 0000000..8fd7a61 --- /dev/null +++ b/ksim/monitors/filesystem/configure.in.in @@ -0,0 +1,2 @@ +AC_CHECK_HEADERS(sys/mnttab.h mntent.h sys/statvfs.h sys/statfs.h sys/vfs.h sys/mount.h sys/ucred.h sys/loadavg.h) +AC_CHECK_FUNCS(statvfs) diff --git a/ksim/monitors/filesystem/filesystemstats.cpp b/ksim/monitors/filesystem/filesystemstats.cpp new file mode 100644 index 0000000..eeb5c62 --- /dev/null +++ b/ksim/monitors/filesystem/filesystemstats.cpp @@ -0,0 +1,224 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#include "filesystemstats.h" + +#include <qglobal.h> +#include <qfile.h> +#include <qstringlist.h> + +#include <kdebug.h> + +#include <config.h> + +#include <sys/types.h> +#include <sys/param.h> + +#if defined(HAVE_SYS_STATVFS_H) && !defined(__DragonFly__) +#include <sys/statvfs.h> +#elif defined( HAVE_SYS_STATFS_H ) +#include <sys/statfs.h> +#endif +#ifdef HAVE_SYS_VFS_H +#include <sys/vfs.h> +#endif +#ifdef HAVE_SYS_MOUNT_H +#include <sys/mount.h> +#endif +#ifdef HAVE_MNTENT_H +#include <mntent.h> +#ifdef _HPUX_SOURCE +#define _PATH_MOUNTED MNTTAB +#endif +#endif +#ifdef HAVE_SYS_UCRED_H +#include <sys/ucred.h> +#endif +#ifdef HAVE_SYS_MNTTAB_H +#include <sys/mnttab.h> +#undef HAVE_MNTENT_H +#define _PATH_MOUNTED MNTTAB +#endif + +#include <stdio.h> +#include <unistd.h> + +#if defined(HAVE_STATVFS) && !defined(__DragonFly__) +typedef struct statvfs ksim_statfs; +#define ksim_getfsstat getvfsstat +#elif defined( HAVE_STATFS ) || defined( Q_OS_FREEBSD ) +typedef struct statfs ksim_statfs; +#define ksim_getfsstat getfsstat +#else +typedef struct // fall back for (possibly) non-supported systems +{ + int f_blocks; + int f_bfree; +} ksim_statfs; +#endif + +int fsystemStats( const char * file, ksim_statfs & stats ) +{ +#if defined(HAVE_STATVFS) && !defined(__DragonFly__) + return statvfs( file, &stats ); +#elif defined( HAVE_STATFS ) || defined( Q_OS_FREEBSD ) + return statfs( file, &stats ); +#else // fall back for (possibly) non-supported systems + (void)file; + + stats.f_blocks = 0; + stats.f_bfree = 0; + return -1; +#endif +} + +#ifdef HAVE_SYS_MNTTAB_H +#define USE_MNTENT + +typedef struct +{ + const char * mnt_dir; + const char * mnt_fsname; + const char * mnt_type; +} ksim_mntent; + +FILE * setmntent( const char * mtab, const char * mode ) +{ + return fopen( mtab, mode ); +} + +int endmntent( FILE * file ) +{ + return fclose( file ); +} + +ksim_mntent * ksim_getmntent( FILE * file ) +{ + ksim_mntent * entry; + struct mnttab tab; + + if ( getmntent( file, &tab ) != 0 ) + return NULL; + + entry = new ksim_mntent; + entry->mnt_dir = tab.mnt_mountp; + entry->mnt_fsname = tab.mnt_special; + entry->mnt_type = tab.mnt_fstype; + return entry; +} + +#define delete_mntent( x ) delete x +#elif defined( HAVE_MNTENT_H ) +#define USE_MNTENT + +// Dummy setup +typedef struct mntent ksim_mntent; +ksim_mntent * ksim_getmntent( FILE * file ) +{ + return getmntent( file ); +} + +#define delete_mntent( x ) +#elif defined( HAVE_SYS_UCRED_H ) || defined( HAVE_SYS_MOUNT_H ) +#define USE_FSSTAT +#else +#define USE_FAILSAFE +#endif + +FilesystemStats::List FilesystemStats::readEntries() +{ + List list; + +#ifdef USE_MNTENT + FILE * fp = setmntent( _PATH_MOUNTED, "r" ); + ksim_mntent * point; + + while ( ( point = ksim_getmntent( fp ) ) != 0 ) + { + Entry entry; + entry.dir = point->mnt_dir; + entry.fsname = point->mnt_fsname; + entry.type = point->mnt_type; + list.append( entry ); + + delete_mntent( point ); + } + + endmntent( fp ); +#endif + +#ifdef USE_FSSTAT + ksim_statfs sfs[32]; + int fs_count; + if ( ( fs_count = ksim_getfsstat( sfs, sizeof( sfs ), 0 ) ) != -1 ) + { + for ( int i = 0; i < fs_count; i++ ) + { + Entry entry; + entry.dir = sfs[i].f_mntonname; + entry.fsname = sfs[i].f_mntfromname; + +#ifndef __osf__ + entry.type = sfs[i].f_fstypename; +#endif + + list.append( entry ); + } + } +#endif + +#ifdef USE_FAILSAFE + QFile file( QString::fromLatin1( _PATH_MOUNTED ) ); + + if ( !file.open( IO_ReadOnly ) ) + return list; + + QTextStream stream( &file ); + + while ( !stream.atEnd() ) + { + QStringList line = QStringList::split( " ", stream.readLine() ); + + Entry entry; + entry.dir = line[1].stripWhiteSpace(); + entry.fsname = line[0].stripWhiteSpace(); + entry.type = line[2].stripWhiteSpace(); + list.append( entry ); + } +#endif + + return list; +} + +bool FilesystemStats::readStats( const QString & mntPoint, int & totalBlocks, int & freeBlocks ) +{ + ksim_statfs sysStats; + if ( fsystemStats( QFile::encodeName( mntPoint ).data(), sysStats ) < 0 ) + { + kdError() << "While reading filesystem information for " << mntPoint << endl; + totalBlocks = 0; + freeBlocks = 0; + } + + totalBlocks = sysStats.f_blocks; + freeBlocks = sysStats.f_bfree; + + // Return true if our filesystem is statable + return totalBlocks > 0; +} diff --git a/ksim/monitors/filesystem/filesystemstats.h b/ksim/monitors/filesystem/filesystemstats.h new file mode 100644 index 0000000..3ea8f74 --- /dev/null +++ b/ksim/monitors/filesystem/filesystemstats.h @@ -0,0 +1,40 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#ifndef FILESYSTEMSTATS_H +#define FILESYSTEMSTATS_H + +#include <qstring.h> +#include <qvaluelist.h> + +namespace FilesystemStats +{ + struct Entry + { + QString dir; + QString fsname; + QString type; + }; + + typedef QValueList<Entry> List; + List readEntries(); + bool readStats( const QString &, int &, int & ); + +} +#endif diff --git a/ksim/monitors/filesystem/filesystemwidget.cpp b/ksim/monitors/filesystem/filesystemwidget.cpp new file mode 100644 index 0000000..0428ee3 --- /dev/null +++ b/ksim/monitors/filesystem/filesystemwidget.cpp @@ -0,0 +1,232 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#include "filesystemwidget.h" + +#include <pluginmodule.h> + +#include <qlayout.h> +#include <qpopupmenu.h> +#include <qregexp.h> +#include <qcursor.h> + +#include <kprocess.h> +#include <kmessagebox.h> +#include <klocale.h> +#include <kiconloader.h> +#include <kdebug.h> + +FilesystemWidget::Filesystem::Filesystem() +{ + m_display = 0; +} + +FilesystemWidget::Filesystem::Filesystem(KSim::Progress *display, + const QString &point) +{ + m_display = display; + m_mountPoint = point; +} + +FilesystemWidget::Filesystem::~Filesystem() +{ + delete m_display; +} + +KSim::Progress *FilesystemWidget::Filesystem::display() const +{ + return m_display; +} + +const QString &FilesystemWidget::Filesystem::mountPoint() const +{ + return m_mountPoint; +} + +const QString &FilesystemWidget::Filesystem::text() const +{ + return m_display->text(); +} + +int FilesystemWidget::Filesystem::value() const +{ + return m_display->value(); +} + +void FilesystemWidget::Filesystem::setText(const QString &text) +{ + if (!m_display) + return; + + m_display->setText(text); +} + +void FilesystemWidget::Filesystem::setValue(int value) +{ + if (!m_display) + return; + + m_display->setValue(value); +} + +FilesystemWidget::FilesystemWidget(QWidget *parent, const char *name) + : QWidget(parent, name) +{ + m_list.setAutoDelete(true); + m_layout = new QVBoxLayout(this); + m_process = 0; +} + +FilesystemWidget::~FilesystemWidget() +{ + delete m_process; +} + +void FilesystemWidget::append(int max, const QString &mountPoint) +{ + KSim::Progress *progress = new KSim::Progress(max, this); + progress->installEventFilter(this); + progress->show(); + m_layout->addWidget(progress); + + m_list.append(new Filesystem(progress, mountPoint)); +} + +void FilesystemWidget::setText(uint id, const QString &text) +{ + if (id > m_list.count()) + return; + + m_list.at(id)->setText(text); +} + +void FilesystemWidget::setValue(uint id, int value) +{ + if (id > m_list.count()) + return; + + m_list.at(id)->setValue(value); +} + +void FilesystemWidget::clear() +{ + m_list.clear(); +} + +bool FilesystemWidget::eventFilter(QObject *o, QEvent *e) +{ + if (!o->isA("KSim::Progress")) + return QWidget::eventFilter(o, e); + + KSim::Progress *progressBar = 0; + int i = 0; + QPtrListIterator<Filesystem> it(m_list); + Filesystem *filesystem; + while ((filesystem = it.current()) != 0) { + ++it; + + if (filesystem->display() == o) { + progressBar = filesystem->display(); + break; + } + + ++i; + } + + if (o == progressBar && e->type() == QEvent::MouseButtonPress) + { + switch(static_cast<QMouseEvent *>(e)->button()) { + case QMouseEvent::RightButton: + showMenu(i); + break; + default: + break; + case QMouseEvent::LeftButton: + if (parentWidget()->inherits("KSim::PluginView")) + static_cast<KSim::PluginView *>(parentWidget())->doCommand(); + break; + } + + return true; + } + + return QWidget::eventFilter(o, e); +} + +void FilesystemWidget::receivedStderr(KProcess *, char *buffer, int length) +{ + m_stderrString.setLatin1(buffer, length); +} + +void FilesystemWidget::processExited(KProcess *) +{ + delete m_process; + m_process = 0; + kdDebug(2003) << "Deleting KProcess pointer" << endl; + + if (m_stderrString.isEmpty()) + return; + + QStringList errorList = QStringList::split("\n", m_stderrString); + QString message = i18n("<qt>The following errors occurred:<ul>"); + + QStringList::Iterator it; + for (it = errorList.begin(); it != errorList.end(); ++it) { + message += QString::fromLatin1("<li>%1</li>") + .arg((*it).replace(QRegExp("[u]?mount: "), QString::null)); + } + + message += QString::fromLatin1("</ul></qt>"); + KMessageBox::sorry(0, message); +} + +void FilesystemWidget::createProcess(const QString &command, const QString &point) +{ + m_process = new KProcess(); + connect(m_process, + SIGNAL(receivedStderr(KProcess *, char *, int)), + SLOT(receivedStderr(KProcess *, char *, int))); + connect(m_process, + SIGNAL(processExited(KProcess *)), + SLOT(processExited(KProcess *))); + + (*m_process) << command << point; + void(m_process->start(KProcess::NotifyOnExit, KProcess::Stderr)); +} + +void FilesystemWidget::showMenu(uint id) +{ + if (id > m_list.count()) + return; + + QPopupMenu menu; + menu.insertItem(SmallIcon("hdd_mount"), i18n("&Mount Device"), 1); + menu.insertItem(SmallIcon("hdd_unmount"), i18n("&Unmount Device"), 2); + + switch (menu.exec(QCursor::pos())) { + case 1: + createProcess("mount", m_list.at(id)->mountPoint()); + break; + case 2: + createProcess("umount", m_list.at(id)->mountPoint()); + break; + } +} + +#include "filesystemwidget.moc" diff --git a/ksim/monitors/filesystem/filesystemwidget.h b/ksim/monitors/filesystem/filesystemwidget.h new file mode 100644 index 0000000..d169b9a --- /dev/null +++ b/ksim/monitors/filesystem/filesystemwidget.h @@ -0,0 +1,78 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#ifndef FSYSTEM_WIDGET_H +#define FSYSTEM_WIDGET_H + +#include <progress.h> + +#include <qptrlist.h> + +class KProcess; +class QVBoxLayout; + +class FilesystemWidget : public QWidget +{ + Q_OBJECT + public: + FilesystemWidget(QWidget *parent, const char *name); + ~FilesystemWidget(); + + void append(int, const QString &); + void setText(uint, const QString &); + void setValue(uint, int); + void clear(); + + protected: + bool eventFilter(QObject *, QEvent *); + + private slots: + void receivedStderr(KProcess *, char *, int); + void processExited(KProcess *); + + private: + class Filesystem + { + public: + Filesystem(); + Filesystem(KSim::Progress *, const QString &); + ~Filesystem(); + + KSim::Progress *display() const; + const QString &mountPoint() const; + const QString &text() const; + int value() const; + + void setText(const QString &); + void setValue(int); + + QString m_mountPoint; + KSim::Progress *m_display; + }; + + void createProcess(const QString &, const QString &); + void showMenu(uint); + + typedef QPtrList<Filesystem> ProgressList; + ProgressList m_list; + QVBoxLayout *m_layout; + KProcess *m_process; + QString m_stderrString; +}; +#endif diff --git a/ksim/monitors/filesystem/fsystemconfig.cpp b/ksim/monitors/filesystem/fsystemconfig.cpp new file mode 100644 index 0000000..9b07ee4 --- /dev/null +++ b/ksim/monitors/filesystem/fsystemconfig.cpp @@ -0,0 +1,184 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#include "fsystemconfig.h" +#include "fsystemconfig.moc" + +#include <kconfig.h> +#include <klocale.h> +#include <kiconloader.h> +#include <klistview.h> +#include <kapplication.h> +#include <knuminput.h> +#include <kdebug.h> + +#include <qcheckbox.h> +#include <qlayout.h> +#include <qtooltip.h> +#include <qlabel.h> +#include <qwhatsthis.h> + +class FSysViewItem : public QCheckListItem +{ + public: + FSysViewItem(QListView *parent, const QString &text1, + const QString &text2, const QString &text3) + : QCheckListItem(parent, text1, CheckBox) + { + setText(1, text2); + setText(2, text3); + } +}; + +FsystemConfig::FsystemConfig(KSim::PluginObject *parent, const char *name) + : KSim::PluginPage(parent, name) +{ + m_mainLayout = new QGridLayout(this); + m_mainLayout->setSpacing(6); + + m_availableMounts = new KListView(this); + m_availableMounts->addColumn(i18n("Mounted Partition")); + m_availableMounts->addColumn(i18n("Device")); + m_availableMounts->addColumn(i18n("Type")); + m_mainLayout->addMultiCellWidget(m_availableMounts, 0, 0, 0, 3); + + m_showPercentage = new QCheckBox(this); + m_showPercentage->setText(i18n("Show percentage")); + m_mainLayout->addMultiCellWidget(m_showPercentage, 1, 1, 0, 3); + + m_splitNames = new QCheckBox(this); + m_splitNames->setText(i18n("Display short mount point names")); + QWhatsThis::add(m_splitNames, i18n("This option shortens the text" + " to shrink down a mount point. E.G: a mount point /home/myuser" + " would become myuser.")); + m_mainLayout->addMultiCellWidget(m_splitNames, 2, 2, 0, 3); + + m_intervalLabel = new QLabel(this); + m_intervalLabel->setText( i18n("Update interval:")); + m_intervalLabel->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, + QSizePolicy::Fixed)); + m_mainLayout->addMultiCellWidget(m_intervalLabel, 3, 3, 0, 0); + + m_updateTimer = new KIntSpinBox(this); + m_updateTimer->setValue(60); + QToolTip::add(m_updateTimer, i18n("0 means no update")); + m_mainLayout->addMultiCellWidget(m_updateTimer, 3, 3, 1, 1); + + QLabel *intervalLabel = new QLabel(this); + intervalLabel->setText(i18n("seconds")); + intervalLabel->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, + QSizePolicy::Fixed)); + m_mainLayout->addMultiCellWidget(intervalLabel, 3, 3, 2, 2); + + m_entries = FilesystemStats::readEntries(); + getStats(); +} + +FsystemConfig::~FsystemConfig() +{ +} + +void FsystemConfig::readConfig() +{ + config()->setGroup("Fsystem"); + m_showPercentage->setChecked(config()->readBoolEntry("ShowPercentage", true)); + m_updateTimer->setValue(config()->readNumEntry("updateValue", 60)); + m_splitNames->setChecked(config()->readBoolEntry("ShortenEntries", false)); + + if (!m_availableMounts->childCount()) + return; + + QStringList list = config()->readListEntry("mountEntries"); + for (QListViewItemIterator it(m_availableMounts); it.current(); ++it) { + QString string = it.current()->text(0) + ":" + splitString(it.current()->text(0)); + static_cast<QCheckListItem *>(it.current())->setOn(list.contains(string) > 0); + } +} + +void FsystemConfig::saveConfig() +{ + config()->setGroup("Fsystem"); + config()->writeEntry("ShowPercentage", m_showPercentage->isChecked()); + config()->writeEntry("updateValue", m_updateTimer->value()); + config()->writeEntry("ShortenEntries", m_splitNames->isChecked()); + + QStringList list; + for (QListViewItemIterator it(m_availableMounts); it.current(); ++it) { + if (static_cast<QCheckListItem *>(it.current())->isOn()) + list.append(it.current()->text(0) + ":" + splitString(it.current()->text(0))); + } + + config()->writeEntry("mountEntries", list); +} + +void FsystemConfig::showEvent(QShowEvent *) +{ + // FIXME: Maybe this is the slow method of doing this? + // Eitherway, i need to find a way to only update the list + // if the amount of mounted partitions has changed + FilesystemStats::List entries = FilesystemStats::readEntries(); + if ( entries.count() == m_entries.count() ) + return; + + m_entries = entries; + + // Update the entries to take into account + // any mounted/unmounted filesystems + m_availableMounts->clear(); + getStats(); +} + +void FsystemConfig::getStats() +{ + int total = 0; + int free = 0; + + FilesystemStats::List::ConstIterator it; + for ( it = m_entries.begin(); it != m_entries.end(); ++it ) + { + if ( !FilesystemStats::readStats( ( *it ).dir, total, free ) ) + continue; + + if ( !m_availableMounts->findItem( ( *it ).dir, 0 ) ) + { + (void) new FSysViewItem( m_availableMounts, ( *it ).dir, + ( *it ).fsname, ( *it ).type ); + } + } + + if (!m_availableMounts->childCount()) + return; + + config()->setGroup("Fsystem"); + QStringList list = config()->readListEntry("mountEntries"); + for (QListViewItemIterator it(m_availableMounts); it.current(); ++it) { + QString string = it.current()->text(0) + ":" + splitString(it.current()->text(0)); + static_cast<QCheckListItem *>(it.current())->setOn(list.contains(string) > 0); + } +} + +QString FsystemConfig::splitString(const QString &string) const +{ + if (string == "/" || !m_splitNames->isChecked()) + return string; + + int location = string.findRev("/"); + QString newString(string); + return newString.remove(0, location + 1); +} diff --git a/ksim/monitors/filesystem/fsystemconfig.h b/ksim/monitors/filesystem/fsystemconfig.h new file mode 100644 index 0000000..353dcf8 --- /dev/null +++ b/ksim/monitors/filesystem/fsystemconfig.h @@ -0,0 +1,58 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#ifndef FSYSTEMCONFIG_H +#define FSYSTEMCONFIG_H + +#include <pluginmodule.h> +#include "filesystemstats.h" + +class KIntSpinBox; +class KListView; +class QGridLayout; +class QCheckBox; +class QLabel; +class QListBoxItem; + +class FsystemConfig : public KSim::PluginPage +{ + Q_OBJECT + public: + FsystemConfig(KSim::PluginObject *parent, const char *name); + ~FsystemConfig(); + + virtual void saveConfig(); + virtual void readConfig(); + + protected: + void showEvent(QShowEvent *); + + private: + void getStats(); + QString splitString(const QString &string) const; + + QCheckBox *m_showPercentage; + QCheckBox *m_splitNames; + QLabel *m_intervalLabel; + KIntSpinBox *m_updateTimer; + KListView *m_availableMounts; + QGridLayout *m_mainLayout; + FilesystemStats::List m_entries; +}; +#endif // FILESYSTEM_H diff --git a/ksim/monitors/filesystem/fsystemiface.h b/ksim/monitors/filesystem/fsystemiface.h new file mode 100644 index 0000000..d590776 --- /dev/null +++ b/ksim/monitors/filesystem/fsystemiface.h @@ -0,0 +1,32 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 - 2004 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#ifndef FSYSTEMIFACE_H +#define FSYSTEMIFACE_H + +#include <dcopobject.h> + +class FsystemIface : virtual public DCOPObject +{ + K_DCOP + k_dcop: + virtual int totalFreeSpace() const = 0; +}; + +#endif // FSYSTEMIFACE_H diff --git a/ksim/monitors/filesystem/ksimfsystem.cpp b/ksim/monitors/filesystem/ksimfsystem.cpp new file mode 100644 index 0000000..3303f6d --- /dev/null +++ b/ksim/monitors/filesystem/ksimfsystem.cpp @@ -0,0 +1,202 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * $Id$ + * + * 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. + */ + +#include <config.h> + +#include <qlayout.h> +#include <qvaluelist.h> +#include <qtimer.h> +#include <qfile.h> +#include <qregexp.h> + +#include <kdebug.h> +#include <klocale.h> +#include <kaboutapplication.h> +#include <kaboutdata.h> +#include <kapplication.h> +#include <kconfig.h> + +#include "ksimfsystem.h" +#include "fsystemconfig.h" +#include "filesystemwidget.h" +#include "filesystemstats.h" +#include <themeloader.h> + +KSIM_INIT_PLUGIN(PluginModule) + +PluginModule::PluginModule(const char *name) + : KSim::PluginObject(name) +{ + setConfigFileName(instanceName()); +} + +PluginModule::~PluginModule() +{ +} + +KSim::PluginView *PluginModule::createView(const char *className) +{ + return new Fsystem(this, className); +} + +KSim::PluginPage *PluginModule::createConfigPage(const char *className) +{ + return new FsystemConfig(this, className); +} + +void PluginModule::showAbout() +{ + QString version = kapp->aboutData()->version(); + + KAboutData aboutData(instanceName(), + I18N_NOOP("KSim FileSystem Plugin"), version.latin1(), + I18N_NOOP("A filesystem plugin for KSim"), + KAboutData::License_GPL, "(C) 2001 Robbie Ward"); + + aboutData.addAuthor("Robbie Ward", I18N_NOOP("Author"), + "linuxphreak@gmx.co.uk"); + aboutData.addAuthor("Jason Katz-Brown", I18N_NOOP("Some Fixes"), + "jason@katzbrown.com"); + aboutData.addAuthor("Heitham Omar", I18N_NOOP("FreeBSD ports"), + "super_ice@ntlworld.com"); + + KAboutApplication(&aboutData).exec(); +} + +Fsystem::Fsystem(KSim::PluginObject *parent, const char *name) + : DCOPObject("fsystem"), + KSim::PluginView(parent, name) +{ + config()->setGroup("Fsystem"); + QVBoxLayout *vbLayout = new QVBoxLayout(this); + vbLayout->setAutoAdd(true); + + QSpacerItem *item = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Expanding); + vbLayout->addItem(item); + + m_mountEntries = makeList(config()->readListEntry("mountEntries")); + m_showPercentage = config()->readBoolEntry("ShowPercentage", true); + + m_widget = new FilesystemWidget(this, "FilesystemWidget"); + + createFreeInfo(); + + m_updateTimer = new QTimer(this); + connect(m_updateTimer, SIGNAL(timeout()), SLOT(updateFS())); + m_updateTimer->start(config()->readNumEntry("updateValue", 60) * 1000); +} + +Fsystem::~Fsystem() +{ +} + +void Fsystem::reparseConfig() +{ + config()->setGroup("Fsystem"); + + m_showPercentage = config()->readBoolEntry("ShowPercentage", true); + MountEntryList mountEntries = makeList(config()->readListEntry("mountEntries")); + + if (m_mountEntries != mountEntries) { + m_widget->clear(); + m_mountEntries = mountEntries; + createFreeInfo(); + } + + updateFS(); +} + +int Fsystem::totalFreeSpace() const +{ + int totalSize, totalFree; + int totalFreeSpace = 0; + MountEntryList::ConstIterator it; + for (it = m_mountEntries.begin(); it != m_mountEntries.end(); ++it) { + if ( FilesystemStats::readStats( ( *it ).first, totalSize, totalFree ) ) + totalFreeSpace += totalFree; + } + + return totalFreeSpace; +} + +void Fsystem::createFreeInfo() +{ + int total, free; + int i = 0; + MountEntryList::ConstIterator it; + for (it = m_mountEntries.begin(); it != m_mountEntries.end(); ++it) { + // returns the total space and free space from *it + // (the current mounted partition) + if ( !FilesystemStats::readStats( ( *it ).first, total, free ) ) + continue; + + int percent = 0; + if( total != 0) + percent = ((total - free) * 100) / total; + m_widget->append(total, (*it).first); + m_widget->setValue(i, total - free); + if (m_showPercentage) + m_widget->setText(i, ((*it).second.isEmpty() ? (*it).first : (*it).second) + + " - " + QString::number(percent) + "%"); + else + m_widget->setText(i, ((*it).second.isEmpty() ? (*it).first : (*it).second)); + i++; + } +} + +void Fsystem::updateFS() +{ + int total, free; + int i = 0; + MountEntryList::ConstIterator it; + for (it = m_mountEntries.begin(); it != m_mountEntries.end(); ++it) { + // returns the total space and free space from *it + // (the current mounted partition) + if ( !FilesystemStats::readStats( ( *it ).first, total, free ) ) + continue; + + int percent = 0; + if( total != 0 ) + percent = ((total - free) * 100) / total; + m_widget->setValue(i, total - free); + if (m_showPercentage) + m_widget->setText(i, ((*it).second.isEmpty() ? (*it).first : (*it).second) + + " - " + QString::number(percent) + "%"); + else + m_widget->setText(i, ((*it).second.isEmpty() ? (*it).first : (*it).second)); + i++; + } +} + +Fsystem::MountEntryList Fsystem::makeList(const QStringList &list) const +{ + MountEntryList newList; + QStringList splitList; + QStringList::ConstIterator it; + for (it = list.begin(); it != list.end(); ++it) { + splitList = QStringList::split(":", (*it)); + newList.append(qMakePair(splitList[0], splitList[1])); + } + + return newList; +} + +#include "ksimfsystem.moc" diff --git a/ksim/monitors/filesystem/ksimfsystem.h b/ksim/monitors/filesystem/ksimfsystem.h new file mode 100644 index 0000000..c3d403f --- /dev/null +++ b/ksim/monitors/filesystem/ksimfsystem.h @@ -0,0 +1,76 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#ifndef FSYSTEM_H +#define FSYSTEM_H + +#include <pluginmodule.h> +#include "fsystemiface.h" + +class KPopupMenu; +class FilesystemWidget; +class QTimer; + +/** + * This class is the filesystem monitor plugin + * + * @author Robbie Ward <linuxphreak@gmx.co.uk> + * @version 0.1 + */ +class PluginModule : public KSim::PluginObject +{ + public: + PluginModule(const char *name); + ~PluginModule(); + + virtual KSim::PluginView *createView(const char *); + virtual KSim::PluginPage *createConfigPage(const char *); + + virtual void showAbout(); +}; + +class Fsystem : public KSim::PluginView, public FsystemIface +{ + Q_OBJECT + public: + /** + * construtor of Fsystem, calls all init functions to create the plugin. + */ + Fsystem(KSim::PluginObject *parent, const char *name); + ~Fsystem(); + + virtual void reparseConfig(); + int totalFreeSpace() const; + + public slots: + void createFreeInfo(); + + private slots: + void updateFS(); + + private: + typedef QValueList<QPair<QString, QString> > MountEntryList; + MountEntryList makeList(const QStringList &list) const; + + FilesystemWidget *m_widget; + QTimer *m_updateTimer; + MountEntryList m_mountEntries; + bool m_showPercentage; +}; +#endif diff --git a/ksim/monitors/i8k/Makefile.am b/ksim/monitors/i8k/Makefile.am new file mode 100644 index 0000000..d46a0d9 --- /dev/null +++ b/ksim/monitors/i8k/Makefile.am @@ -0,0 +1,15 @@ +kde_module_LTLIBRARIES = ksim_i8k.la +ksim_i8k_la_SOURCES = ksimi8k.cpp + +ksim_i8k_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +ksim_i8k_la_LIBADD = ../../library/libksimcore.la + +EXTRA_DIST = i8k.desktop + +INCLUDES= -I$(top_srcdir)/ksim/library \ + $(all_includes) + +METASOURCES = AUTO + +mon_DATA = i8k.desktop +mondir = $(kde_datadir)/ksim/monitors diff --git a/ksim/monitors/i8k/i8k.desktop b/ksim/monitors/i8k/i8k.desktop new file mode 100644 index 0000000..322fda3 --- /dev/null +++ b/ksim/monitors/i8k/i8k.desktop @@ -0,0 +1,62 @@ +[Desktop Entry] +Comment=Dell I8K Hardware Monitor Plugin +Comment[ar]=ملØÙ‚ لمراقبة عتاد Dell I8K +Comment[bg]=Мониторинг на Dell I8K +Comment[bs]=Dell I8K dodatak za nadzor hardvera +Comment[ca]=Connector per a controlar el maquinari Dell I8K +Comment[cs]=Modul sledovánà hardwaru pro Dell I8K +Comment[cy]=Ategyn Arsylwydd Caledwedd Dell I8K +Comment[de]=Dell I8K Hardware Ãœberwachungs-Plugin +Comment[el]=Î Ïόσθετο εποπτείας Ï…Î»Î¹ÎºÎ¿Ï Dell I8K +Comment[es]=Extensión de monitorización de hardware para Dell I8K +Comment[et]=Dell I8K riistvara monitooringu plugin +Comment[eu]=Dell I8K Hardwarearen Plugin Begiralea +Comment[fa]=وصلۀ نمایشگر سخت‌اÙزار Dell I8K +Comment[fi]=Dell I8K-laitteistomonitoriliitännäinen +Comment[fr]=Module de surveillance du Dell l8K +Comment[ga]=Breiseán Monatóireachta Cruaearraà Dell I8K +Comment[hi]=डेल I8K हारà¥à¤¡à¤µà¥‡à¤¯à¤° मॉनीटर पà¥à¤²à¤—इन +Comment[hu]=Dell I8K hardvermonitor bÅ‘vÃtÅ‘modul +Comment[is]=Ãforrit til að fylgjast með Dell I8K vélbúnaði +Comment[it]=Plugin di controllo hardware Dell I8K +Comment[ja]=Dell I8K ãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢ãƒ¢ãƒ‹ã‚¿ãƒ—ラグイン +Comment[ka]=Dell I8K მáƒáƒ¬áƒ§áƒáƒ‘ილáƒáƒ‘áƒáƒ—რმáƒáƒœáƒ˜áƒ¢áƒáƒ ის მáƒáƒ“ული +Comment[kk]=Dell I8K жабдықтарын бақылау модулі +Comment[km]=កម្មវិធី​ជំនួយ​របស់​កម្មវិធី​ážáŸ’ážšáž½ážáž–áž·áž“áž·ážáŸ’យផ្នែករឹង Dell I8K +Comment[lt]=Dell I8K aparatinÄ—s įrangos stebÄ—jimo priedas +Comment[mk]=Приклучок за Ñледење на хардверот Dell I8K +Comment[ms]=Plug masuk Pemerhati Perkakasan Dell I8K +Comment[nb]=Programtillegg for overvÃ¥kning av maskinvare Dell I8K +Comment[nds]=Kiekmoduul för Dell I8K-Hardware +Comment[ne]=डेल I8K हारà¥à¤¡à¤µà¥‡à¤¯à¤° मोनिटर पà¥à¤²à¤—इन +Comment[nl]=Dell I8000 Hardware Monitor-plugin +Comment[nn]=Programtillegg for overvaking av Dell I8K-maskinvare +Comment[pa]=Dell I8K ਜੰਤਰ ਨਿਗਰਾਨ ਪਲੱਗਿੰਨ +Comment[pl]=Wtyczka monitorowania Dell I8K +Comment[pt]='Plugin' de monitorização de hardware para o Dell I8K +Comment[pt_BR]=Plug-in de monitoramento do Hardware Dell I8K +Comment[ro]=Modul monitorizare Dell I8K +Comment[ru]=Модуль монитора Ð¾Ð±Ð¾Ñ€ÑƒÐ´Ð¾Ð²Ð°Ð½Ð¸Ñ Dell I8K +Comment[sk]=Modul pre monitorovanie hardware Dell I8K +Comment[sl]=Vstavek za opazovanje strojne opreme Dell I8K +Comment[sr]=Прикључак за надгледање Dell-овог I8K хардвера +Comment[sr@Latn]=PrikljuÄak za nadgledanje Dell-ovog I8K hardvera +Comment[sv]=Insticksprogram för Dell I8K-övervakning +Comment[ta]=டெலà¯I8K வனà¯à®ªà¯Šà®°à¯à®³à¯ கணà¯à®•à®¾à®£à®¿ சொரà¯à®•à¯à®ªà¯Šà®°à¯à®³à¯ +Comment[tg]=Модули Дидабони Сахтафзори Dell I8K +Comment[tr]=Dell I8K Donanım Monitör Plugini +Comment[uk]=Втулок датчика апаратного Ð·Ð°Ð±ÐµÐ·Ð¿ÐµÑ‡ÐµÐ½Ð½Ñ Dell I8K +Comment[wa]=Tchôke-divins di corwaitaedje di l' éndjolreye pol Dell I8K +Comment[zh_CN]=Dell I8K 硬件邮件监视器æ’件 +Comment[zh_TW]=Dell I8K ç¡¬é«”ç›£è¦–å™¨å¤–æŽ›ç¨‹å¼ +Icon=hdd_mount +Name=Dell I8K +Name[fr]=Dell l8K +Name[he]=Dell l8k +Name[hi]=डेल I8K +Name[nb]=Dell 18K +Name[ne]=डेल I8K +Name[sr]=Dell-ов I8K +Name[sr@Latn]=Dell-ov I8K +Name[ta]= டெல௠I8K +X-KSIM-LIBRARY=i8k diff --git a/ksim/monitors/i8k/ksimi8k.cpp b/ksim/monitors/i8k/ksimi8k.cpp new file mode 100644 index 0000000..ff995b0 --- /dev/null +++ b/ksim/monitors/i8k/ksimi8k.cpp @@ -0,0 +1,257 @@ +/* Dell i8K Hardware Monitor Plug-in for KSim + * + * Copyright (C) 2003 Nadeem Hasan <nhasan@kde.org> + * + * 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. + */ + +#include "ksimi8k.h" + +#include <qlayout.h> +#include <qtimer.h> +#include <qfile.h> +#include <qtextstream.h> +#include <qregexp.h> +#include <qlabel.h> +#include <qcheckbox.h> + +#include <label.h> +#include <klocale.h> +#include <kapplication.h> +#include <kconfig.h> +#include <kaboutapplication.h> +#include <knuminput.h> +#include <kdebug.h> + +KSIM_INIT_PLUGIN(I8KPlugin); + +I8KPlugin::I8KPlugin(const char *name) + : KSim::PluginObject(name) +{ + setConfigFileName(instanceName()); +} + +I8KPlugin::~I8KPlugin() +{ +} + +KSim::PluginView *I8KPlugin::createView(const char *className) +{ + return new I8KView(this, className); +} + +KSim::PluginPage *I8KPlugin::createConfigPage(const char *className) +{ + return new I8KConfig(this, className); +} + +void I8KPlugin::showAbout() +{ + QString version = kapp->aboutData()->version(); + + KAboutData aboutData(instanceName(), + I18N_NOOP("KSim I8K Plugin"), version.latin1(), + I18N_NOOP("Dell I8K Hardware Monitor plugin"), + KAboutData::License_GPL, "(C) 2003 Nadeem Hasan"); + + aboutData.addAuthor("Nadeem Hasan", I18N_NOOP("Author"), + "nhasan@kde.org"); + + KAboutApplication(&aboutData).exec(); +} + +I8KView::I8KView(KSim::PluginObject *parent, const char *name) + : KSim::PluginView(parent, name), + m_timer( 0L ), m_procFile( 0L ), m_procStream( 0L ) +{ + initGUI(); + + m_timer = new QTimer( this ); + + m_reData = new QRegExp( "\\S+\\s+\\S+\\s+\\S+\\s+(\\d+)\\s+\\S+" + "\\s+\\S+\\s+(\\d+)\\s+(\\d+)\\s+\\S+\\s+\\S+" ); + + openStream(); + reparseConfig(); +} + +I8KView::~I8KView() +{ + closeStream(); + + delete m_timer; + delete m_reData; +} + +void I8KView::reparseConfig() +{ + config()->setGroup("I8KPlugin"); + + m_unit = config()->readEntry( "Unit", "C" ); + m_interval = config()->readNumEntry( "Interval", 5 ); + + if ( m_procStream ) + { + m_timer->stop(); + m_timer->start( m_interval*1000 ); + } + + updateView(); +} + +void I8KView::openStream() +{ + kdDebug( 2003 ) << "i8k: Trying /proc/i8k...." << endl; + + m_timer->stop(); + + if ( ( m_procFile = fopen( "/proc/i8k", "r" ) ) ) + { + m_procStream = new QTextIStream( m_procFile ); + disconnect( m_timer, 0, 0, 0 ); + connect( m_timer, SIGNAL( timeout() ), SLOT( updateView() ) ); + m_timer->start( m_interval*1000 ); + + kdDebug( 2003 ) << "i8k: Success" << endl; + } + else + { + // i8k module is not loaded. Try again after 30 secs. + disconnect( m_timer, 0, 0, 0 ); + connect( m_timer, SIGNAL( timeout() ), SLOT( openStream() ) ); + m_timer->start( 30*1000 ); + kdDebug( 2003 ) << "i8k: Failed...retry after 30 secs" << endl; + } +} + +void I8KView::closeStream() +{ + if ( m_procFile ) + fclose( m_procFile ); + + if ( m_procStream ) + delete m_procStream; + + m_procFile = 0L; + m_procStream = 0L; + m_timer->stop(); +} + +void I8KView::initGUI() +{ + QVBoxLayout *layout = new QVBoxLayout( this ); + + m_fan1Label = new KSim::Label( this ); + m_fan2Label = new KSim::Label( this ); + m_tempLabel = new KSim::Label( this ); + + layout->addWidget( m_fan1Label ); + layout->addWidget( m_fan2Label ); + layout->addWidget( m_tempLabel ); +} + +void I8KView::updateView() +{ + kdDebug( 2003 ) << "i8k: Updating..." << endl; + int cputemp=0, rightspeed=0, leftspeed=0; + + if ( m_procStream ) + { + fseek( m_procFile, 0L, SEEK_SET ); + + QString line = m_procStream->read(); + + if ( line.isEmpty() ) + { + // i8k module is no longer available, is it possible? + closeStream(); + openStream(); + return; + } + + if ( m_reData->search( line ) > -1 ) + { + QStringList matches = m_reData->capturedTexts(); + + cputemp = matches[ 1 ].toInt(); + leftspeed = matches[ 2 ].toInt(); + rightspeed = matches[ 3 ].toInt(); + + if ( m_unit == "F" ) + cputemp = ( cputemp*9/5 ) + 32; + } + } + + if ( rightspeed > 0 ) + m_fan1Label->setText( i18n( "Right fan: %1 RPM" ).arg( rightspeed ) ); + else + m_fan1Label->setText( i18n( "Right fan: Off" ) ); + + if ( leftspeed > 0 ) + m_fan2Label->setText( i18n( "Left fan: %1 RPM" ).arg( leftspeed ) ); + else + m_fan2Label->setText( i18n( "Left fan: Off" ) ); + + m_tempLabel->setText( i18n( "CPU temp: %1°%2" ).arg( cputemp ) + .arg( m_unit ) ); +} + +I8KConfig::I8KConfig(KSim::PluginObject *parent, const char *name) + : KSim::PluginPage(parent, name) +{ + m_unit = new QCheckBox( i18n( "Show temperature in Fahrenheit" ), + this ); + QLabel *label = new QLabel( i18n( "Update interval:" ), this ); + m_interval = new KIntNumInput( this ); + m_interval->setRange( 2, 60, 1, true ); + m_interval->setSuffix( i18n( " sec" ) ); + + QGridLayout *layout = new QGridLayout( this, 3, 2, 0, + KDialog::spacingHint() ); + + layout->addMultiCellWidget( m_unit, 0, 0, 0, 1 ); + layout->addWidget( label, 1, 0 ); + layout->addWidget( m_interval, 1, 1 ); + layout->setColStretch( 1, 1 ); + layout->setRowStretch( 2, 1 ); +} + +I8KConfig::~I8KConfig() +{ +} + +void I8KConfig::readConfig() +{ + config()->setGroup("I8KPlugin"); + + QString unit = config()->readEntry( "Unit", "C" ); + int interval = config()->readNumEntry( "Interval", 5 ); + + m_unit->setChecked( unit == "F" ); + m_interval->setValue( interval ); +} + +void I8KConfig::saveConfig() +{ + config()->setGroup("I8KPlugin"); + + config()->writeEntry( "Unit", m_unit->isChecked()? "F" : "C" ); + config()->writeEntry( "Interval", m_interval->value() ); +} + +#include "ksimi8k.moc" + +/* vim: et sw=2 ts=2 +*/ diff --git a/ksim/monitors/i8k/ksimi8k.h b/ksim/monitors/i8k/ksimi8k.h new file mode 100644 index 0000000..4357508 --- /dev/null +++ b/ksim/monitors/i8k/ksimi8k.h @@ -0,0 +1,102 @@ +/* Dell i8K Hardware Monitor Plug-in for KSim + * + * Copyright (C) 2003 Nadeem Hasan <nhasan@kde.org> + * + * 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. + */ + +#ifndef KSIMI8K_H +#define KSIMI8K_H + +#include <stdio.h> + +#include <pluginmodule.h> + +class QTimer; +class QTextIStream; +class QRegExp; +class QCheckBox; +class KIntNumInput; + +namespace KSim +{ + class Label; +} + +class I8KPlugin : public KSim::PluginObject +{ + public: + I8KPlugin(const char *name); + ~I8KPlugin(); + + virtual KSim::PluginView *createView(const char *); + virtual KSim::PluginPage *createConfigPage(const char *); + + virtual void showAbout(); +}; + +class I8KView : public KSim::PluginView +{ + Q_OBJECT + public: + I8KView(KSim::PluginObject *parent, const char *name); + ~I8KView(); + + virtual void reparseConfig(); + + protected: + + void initGUI(); + void closeStream(); + + protected slots: + + void openStream(); + void updateView(); + + private: + + QString m_unit; + int m_interval; + + KSim::Label *m_fan1Label, *m_fan2Label, *m_tempLabel; + QTimer *m_timer; + FILE *m_procFile; + QTextIStream *m_procStream; + QRegExp *m_reData; +}; + +class I8KConfig : public KSim::PluginPage +{ + Q_OBJECT + public: + I8KConfig(KSim::PluginObject *parent, const char *name); + ~I8KConfig(); + + virtual void saveConfig(); + virtual void readConfig(); + + private slots: + + private: + + QCheckBox *m_unit; + KIntNumInput *m_interval; +}; + +#endif // KSIMI8K_H + +/* vim: et sw=2 ts=2 +*/ diff --git a/ksim/monitors/lm_sensors/Lm_sensors.desktop b/ksim/monitors/lm_sensors/Lm_sensors.desktop new file mode 100644 index 0000000..d700e0d --- /dev/null +++ b/ksim/monitors/lm_sensors/Lm_sensors.desktop @@ -0,0 +1,84 @@ +[Desktop Entry] +Comment=Lm_sensors Status Monitor +Comment[ar]=مراقب Øالة Lm_sensors +Comment[bg]=Мониторинг на Lm_sensors +Comment[bs]=Nadzor statusa lm_sensors +Comment[ca]=Monitor de l'estat de Lm_sensors +Comment[cs]=Monitor stavu lm_sensorů +Comment[cy]=Monitr Statws Lm_sensors +Comment[da]=StatusovervÃ¥gning af lm_følere +Comment[de]=Statusanzeige für LM-Sensoren +Comment[el]=Επόπτης κατάστασης lm_sensors +Comment[eo]=Rigardilo por la stato de Lm-sentiloj +Comment[es]=Monitor de estado de los sensores Lm +Comment[et]=Lm_sensors olekute monitooring +Comment[eu]=Lm_sentsoreen Egoera Begiralea +Comment[fa]=Lm_نمایشگر وضعیت Øسگرهای +Comment[fi]=Lm_sensors tilavalvonta +Comment[fr]=Indicateur d'état lm_sensors +Comment[ga]=Monatóir Stádais Lm_sensors +Comment[he]=צג מצב Lm_sensors +Comment[hi]=à¤à¤²à¤à¤®_सेंसरà¥à¤¸ सà¥à¤¥à¤¿à¤¤à¤¿ मॉनीटर +Comment[hu]=Lm_sensors hardvermonitor +Comment[is]=Eftirlit með stöðu Lm_sensors +Comment[it]=Controllo di stato Lm_sensors +Comment[ja]=Lm センサーã®çŠ¶æ…‹ãƒ¢ãƒ‹ã‚¿ +Comment[ka]=Lm_sensors სტáƒáƒ¢áƒ£áƒ¡áƒ˜áƒ¡ მáƒáƒœáƒ˜áƒ¢áƒáƒ ი +Comment[kk]=Lm_sensor ÑенÑорларының күйін бақылау +Comment[km]=កម្មវិធី​ážáŸ’ážšáž½ážáž–áž·áž“áž·ážáŸ’យ​ស្ážáž¶áž“ភាព Lm_sensors +Comment[lt]=Lm_sensors bÅ«senos stebÄ—tojas +Comment[mk]=Монитор за ÑтатуÑот на Lm_sensors +Comment[ms]=Pemerhati Status Lm_sensors +Comment[nb]=StatusovervÃ¥kning av Lm_sensorer +Comment[nds]=LM_Sensors-Statuskieker +Comment[ne]=Lm_sensors सà¥à¤¥à¤¿à¤¤à¤¿ मोनिटर +Comment[nl]=Lm_sensors statusmonitor +Comment[nn]=Lm_sensors-statusovervaking +Comment[pa]=Lm_sensors ਹਾਲਤ ਨਿਗਰਾਨ +Comment[pl]=Stan Lm_sensors +Comment[pt]=Monitor de Estado do Lm_sensors +Comment[pt_BR]=Monitor de estado dos sensores do sistema +Comment[ro]=Monitor stare lm_sensors +Comment[ru]=Монитор ÑоÑтоÑÐ½Ð¸Ñ Ð´Ð°Ñ‚Ñ‡Ð¸ÐºÐ¾Ð² lm_sensors +Comment[sk]=Monitor stavu lm_sensors +Comment[sl]=Nadzornik stanja Lm_senzorji +Comment[sr]=Ðадгледање ÑтатуÑа lm-Ñензора +Comment[sr@Latn]=Nadgledanje statusa lm-senzora +Comment[sv]=Lm_sensors statusövervakare +Comment[ta]=Lm_உணரà¯à®•à®°à¯à®µà®¿ நிலை கணà¯à®•à®¾à®£à®¿ +Comment[tg]=Дидабони Ҳолати Lm_sensors +Comment[th]=Lm_sensors - เครื่à¸à¸‡à¸¡à¸·à¸à¸ªà¸à¸”ส่à¸à¸‡à¸ªà¸–านะ +Comment[tr]=Lm_sensors Durum Ä°zleyici +Comment[uk]=Монітор Ñтану Lm_sensors +Comment[zh_CN]=Lm_sensors 状æ€ç›‘视器 +Comment[zh_TW]=Lm_sensors 狀態監視器 +Comment[zu]=Umlawuli Wezinga we-Lm_sensors +Icon=memory +Name=Lm_sensors +Name[cs]=Lm_sensory +Name[da]=Lm_følere +Name[de]=LM-Sensoren +Name[eo]=Lm-sentiloj +Name[es]=Sensores Lm +Name[eu]=Lm_sentsoreak +Name[fa]=Lm_Øسگرهای +Name[he]=×—×™×™×©× ×™× +Name[hi]=à¤à¤²à¤à¤®_सेंसरà¥à¤¸ +Name[ja]=Lm センサー +Name[kk]=Lm_sensor ÑенÑорлары +Name[ko]=Lm 센서 +Name[lv]=Lm_sensori +Name[nb]=Lm_sensorer +Name[nds]=LM-Sensoren +Name[ro]=Senzori LM +Name[ru]=Датчики lm_sensors +Name[sl]=Lm_senzorji +Name[sr]=Lm-Ñензори +Name[sr@Latn]=Lm-senzori +Name[ta]= Lm_செனà¯à®šà®¾à®°à¯à®¸à¯ +X-KSIM-VERSION=0.1 +X-KSIM-LIBRARY=sensors +X-KSIM-PREFS=Sensors +X-KSIM-AUTHOR=Robbie Ward +X-KSIM-EMAIL=linuxphreak@gmx.co.uk +X-KSIM-COPYRIGHT=(C) 2001 Robbie Ward diff --git a/ksim/monitors/lm_sensors/Makefile.am b/ksim/monitors/lm_sensors/Makefile.am new file mode 100644 index 0000000..182e01c --- /dev/null +++ b/ksim/monitors/lm_sensors/Makefile.am @@ -0,0 +1,26 @@ +kde_module_LTLIBRARIES = ksim_sensors.la + +if include_nv +NVCTRL_LIB= NVCtrl.la +NVCtrl_la_SOURCES = NVCtrl.c +NVCtrl_la_LDFLAGS = -module $(all_libraries) $(KDE_PLUGIN) +endif + +noinst_LTLIBRARIES = $(NVCTRL_LIB) + +ksim_sensors_la_SOURCES = ksimsensors.cpp sensorsconfig.cpp \ + sensorbase.cpp ksimsensorsiface.skel + +ksim_sensors_la_LDFLAGS = $(all_libraries) -module -avoid-version +ksim_sensors_la_LIBADD = ../../library/libksimcore.la $(NVCTRL_LIB) + +EXTRA_DIST = Lm_sensors.desktop + +INCLUDES = -I$(top_srcdir)/ksim/library \ + -I$(top_srcdir)/ksim \ + $(all_includes) + +METASOURCES = AUTO + +mon_DATA = Lm_sensors.desktop +mondir = $(kde_datadir)/ksim/monitors diff --git a/ksim/monitors/lm_sensors/NVCtrl.c b/ksim/monitors/lm_sensors/NVCtrl.c new file mode 100644 index 0000000..6c61b8a --- /dev/null +++ b/ksim/monitors/lm_sensors/NVCtrl.c @@ -0,0 +1,357 @@ +/* + * Copyright (C) 2004 NVIDIA Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of Version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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 Version 2 + * of 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 + * + */ + +#define NEED_EVENTS +#define NEED_REPLIES +#include <X11/Xlibint.h> +#include <X11/Xutil.h> +#include <X11/extensions/Xext.h> +#include <X11/extensions/extutil.h> +#include "NVCtrlLib.h" +#include "nv_control.h" + + +static XExtensionInfo _nvctrl_ext_info_data; +static XExtensionInfo *nvctrl_ext_info = &_nvctrl_ext_info_data; +static const char *nvctrl_extension_name = NV_CONTROL_NAME; + +#define XNVCTRLCheckExtension(dpy,i,val) \ + XextCheckExtension (dpy, i, nvctrl_extension_name, val) +#define XNVCTRLSimpleCheckExtension(dpy,i) \ + XextSimpleCheckExtension (dpy, i, nvctrl_extension_name) + +static int close_display(); +static Bool wire_to_event(); +static const XExtensionHooks nvctrl_extension_hooks = { + NULL, /* create_gc */ + NULL, /* copy_gc */ + NULL, /* flush_gc */ + NULL, /* free_gc */ + NULL, /* create_font */ + NULL, /* free_font */ + close_display, /* close_display */ + wire_to_event, /* wire_to_event */ + NULL, /* event_to_wire */ + NULL, /* error */ + NULL, /* error_string */ +}; + +static XEXT_GENERATE_FIND_DISPLAY (find_display, nvctrl_ext_info, + nvctrl_extension_name, + &nvctrl_extension_hooks, + NV_CONTROL_EVENTS, NULL) + +static XEXT_GENERATE_CLOSE_DISPLAY (close_display, nvctrl_ext_info) + +Bool XNVCTRLQueryExtension ( + Display *dpy, + int *event_basep, + int *error_basep +){ + XExtDisplayInfo *info = find_display (dpy); + + if (XextHasExtension(info)) { + if (event_basep) *event_basep = info->codes->first_event; + if (error_basep) *error_basep = info->codes->first_error; + return True; + } else { + return False; + } +} + + +Bool XNVCTRLQueryVersion ( + Display *dpy, + int *major, + int *minor +){ + XExtDisplayInfo *info = find_display (dpy); + xnvCtrlQueryExtensionReply rep; + xnvCtrlQueryExtensionReq *req; + + if(!XextHasExtension(info)) + return False; + + XNVCTRLCheckExtension (dpy, info, False); + + LockDisplay (dpy); + GetReq (nvCtrlQueryExtension, req); + req->reqType = info->codes->major_opcode; + req->nvReqType = X_nvCtrlQueryExtension; + if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { + UnlockDisplay (dpy); + SyncHandle (); + return False; + } + if (major) *major = rep.major; + if (minor) *minor = rep.minor; + UnlockDisplay (dpy); + SyncHandle (); + return True; +} + + +Bool XNVCTRLIsNvScreen ( + Display *dpy, + int screen +){ + XExtDisplayInfo *info = find_display (dpy); + xnvCtrlIsNvReply rep; + xnvCtrlIsNvReq *req; + Bool isnv; + + if(!XextHasExtension(info)) + return False; + + XNVCTRLCheckExtension (dpy, info, False); + + LockDisplay (dpy); + GetReq (nvCtrlIsNv, req); + req->reqType = info->codes->major_opcode; + req->nvReqType = X_nvCtrlIsNv; + req->screen = screen; + if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { + UnlockDisplay (dpy); + SyncHandle (); + return False; + } + isnv = rep.isnv; + UnlockDisplay (dpy); + SyncHandle (); + return isnv; +} + + +void XNVCTRLSetAttribute ( + Display *dpy, + int screen, + unsigned int display_mask, + unsigned int attribute, + int value +){ + XExtDisplayInfo *info = find_display (dpy); + xnvCtrlSetAttributeReq *req; + + XNVCTRLSimpleCheckExtension (dpy, info); + + LockDisplay (dpy); + GetReq (nvCtrlSetAttribute, req); + req->reqType = info->codes->major_opcode; + req->nvReqType = X_nvCtrlSetAttribute; + req->screen = screen; + req->display_mask = display_mask; + req->attribute = attribute; + req->value = value; + UnlockDisplay (dpy); + SyncHandle (); +} + + +Bool XNVCTRLQueryAttribute ( + Display *dpy, + int screen, + unsigned int display_mask, + unsigned int attribute, + int *value +){ + XExtDisplayInfo *info = find_display (dpy); + xnvCtrlQueryAttributeReply rep; + xnvCtrlQueryAttributeReq *req; + Bool exists; + + if(!XextHasExtension(info)) + return False; + + XNVCTRLCheckExtension (dpy, info, False); + + LockDisplay (dpy); + GetReq (nvCtrlQueryAttribute, req); + req->reqType = info->codes->major_opcode; + req->nvReqType = X_nvCtrlQueryAttribute; + req->screen = screen; + req->display_mask = display_mask; + req->attribute = attribute; + if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { + UnlockDisplay (dpy); + SyncHandle (); + return False; + } + if (value) *value = rep.value; + exists = rep.flags; + UnlockDisplay (dpy); + SyncHandle (); + return exists; +} + + +Bool XNVCTRLQueryStringAttribute ( + Display *dpy, + int screen, + unsigned int display_mask, + unsigned int attribute, + char **ptr +){ + XExtDisplayInfo *info = find_display (dpy); + xnvCtrlQueryStringAttributeReply rep; + xnvCtrlQueryStringAttributeReq *req; + Bool exists; + int length, numbytes, slop; + + if (!ptr) return False; + + if(!XextHasExtension(info)) + return False; + + XNVCTRLCheckExtension (dpy, info, False); + + LockDisplay (dpy); + GetReq (nvCtrlQueryStringAttribute, req); + req->reqType = info->codes->major_opcode; + req->nvReqType = X_nvCtrlQueryStringAttribute; + req->screen = screen; + req->display_mask = display_mask; + req->attribute = attribute; + if (!_XReply (dpy, (xReply *) &rep, 0, False)) { + UnlockDisplay (dpy); + SyncHandle (); + return False; + } + length = rep.length; + numbytes = rep.n; + slop = numbytes & 3; + *ptr = (char *) Xmalloc(numbytes); + if (! *ptr) { + _XEatData(dpy, length); + UnlockDisplay (dpy); + SyncHandle (); + return False; + } else { + _XRead(dpy, (char *) *ptr, numbytes); + if (slop) _XEatData(dpy, 4-slop); + } + exists = rep.flags; + UnlockDisplay (dpy); + SyncHandle (); + return exists; +} + +Bool XNVCTRLQueryValidAttributeValues ( + Display *dpy, + int screen, + unsigned int display_mask, + unsigned int attribute, + NVCTRLAttributeValidValuesRec *values +){ + XExtDisplayInfo *info = find_display (dpy); + xnvCtrlQueryValidAttributeValuesReply rep; + xnvCtrlQueryValidAttributeValuesReq *req; + Bool exists; + + if (!values) return False; + + if(!XextHasExtension(info)) + return False; + + XNVCTRLCheckExtension (dpy, info, False); + + LockDisplay (dpy); + GetReq (nvCtrlQueryValidAttributeValues, req); + req->reqType = info->codes->major_opcode; + req->nvReqType = X_nvCtrlQueryValidAttributeValues; + req->screen = screen; + req->display_mask = display_mask; + req->attribute = attribute; + if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { + UnlockDisplay (dpy); + SyncHandle (); + return False; + } + exists = rep.flags; + values->type = rep.attr_type; + if (rep.attr_type == ATTRIBUTE_TYPE_RANGE) { + values->u.range.min = rep.min; + values->u.range.max = rep.max; + } + if (rep.attr_type == ATTRIBUTE_TYPE_INT_BITS) { + values->u.bits.ints = rep.bits; + } + values->permissions = rep.perms; + UnlockDisplay (dpy); + SyncHandle (); + return exists; +} + +Bool XNVCtrlSelectNotify ( + Display *dpy, + int screen, + int type, + Bool onoff +){ + XExtDisplayInfo *info = find_display (dpy); + xnvCtrlSelectNotifyReq *req; + + if(!XextHasExtension (info)) + return False; + + XNVCTRLCheckExtension (dpy, info, False); + + LockDisplay (dpy); + GetReq (nvCtrlSelectNotify, req); + req->reqType = info->codes->major_opcode; + req->nvReqType = X_nvCtrlSelectNotify; + req->screen = screen; + req->notifyType = type; + req->onoff = onoff; + UnlockDisplay (dpy); + SyncHandle (); + + return True; +} + +static Bool wire_to_event (Display *dpy, XEvent *host, xEvent *wire) +{ + XExtDisplayInfo *info = find_display (dpy); + XNVCtrlEvent *re = (XNVCtrlEvent *) host; + xnvctrlEvent *event = (xnvctrlEvent *) wire; + + XNVCTRLCheckExtension (dpy, info, False); + + switch ((event->u.u.type & 0x7F) - info->codes->first_event) { + case ATTRIBUTE_CHANGED_EVENT: + re->attribute_changed.type = event->u.u.type & 0x7F; + re->attribute_changed.serial = + _XSetLastRequestRead(dpy, (xGenericReply*) event); + re->attribute_changed.send_event = ((event->u.u.type & 0x80) != 0); + re->attribute_changed.display = dpy; + re->attribute_changed.time = event->u.attribute_changed.time; + re->attribute_changed.screen = event->u.attribute_changed.screen; + re->attribute_changed.display_mask = + event->u.attribute_changed.display_mask; + re->attribute_changed.attribute = event->u.attribute_changed.attribute; + re->attribute_changed.value = event->u.attribute_changed.value; + break; + default: + return False; + } + + return True; +} + diff --git a/ksim/monitors/lm_sensors/NVCtrl.h b/ksim/monitors/lm_sensors/NVCtrl.h new file mode 100644 index 0000000..81c9432 --- /dev/null +++ b/ksim/monitors/lm_sensors/NVCtrl.h @@ -0,0 +1,807 @@ +/* + * Copyright (C) 2004 NVIDIA Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of Version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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 Version 2 + * of 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 + * + */ + +#ifndef __NVCTRL_H +#define __NVCTRL_H + +/**************************************************************************/ +/* + * Integer attributes; these are settable/gettable via + * XNVCTRLSetAttribute() and XNVCTRLQueryAttribute, respectively. + * Some attributes may only be read; some may require a display_mask + * argument. This information is encoded in the "permission" comment + * after each attribute #define, and can be queried at run time with + * XNVCTRLQueryValidAttributeValues(). + * + * Key to Integer Attribute "Permissions": + * + * R: The attribute is readable (in general, all attributes will be + * readable) + * + * W: The attribute is writable (attributes may not be writable for + * various reasons: they represent static system information, they + * can only be changed by changing an XF86Config option, etc). + * + * D: The attribute requires the display mask argument. The + * attributes NV_CTRL_CONNECTED_DISPLAYS and NV_CTRL_ENABLED_DISPLAYS + * will be a bitmask of what display devices are connected and what + * display devices are enabled for use in X, respectively. Each bit + * in the bitmask represents a display device; it is these bits which + * should be used as the display_mask when dealing with attributes + * designated with "D" below. For attributes that do not require the + * display mask, the argument is ignored. + */ + + +/**************************************************************************/ + + +/* + * NV_CTRL_FLATPANEL_SCALING - the current flatpanel scaling state; + * possible values are: + * + * 0: default (the driver will use whatever state is current) + * 1: native (the driver will use the panel's scaler, if possible) + * 2: scaled (the driver will use the GPU's scaler, if possible) + * 3: centered (the driver will center the image) + * 4: aspect scaled (scale with the GPU's scaler, but keep the aspect + * ratio correct) + */ + +#define NV_CTRL_FLATPANEL_SCALING 2 /* RWD */ +#define NV_CTRL_FLATPANEL_SCALING_DEFAULT 0 +#define NV_CTRL_FLATPANEL_SCALING_NATIVE 1 +#define NV_CTRL_FLATPANEL_SCALING_SCALED 2 +#define NV_CTRL_FLATPANEL_SCALING_CENTERED 3 +#define NV_CTRL_FLATPANEL_SCALING_ASPECT_SCALED 4 + + +/* + * NV_CTRL_FLATPANEL_DITHERING - the current flatpanel dithering + * state; possible values are: + * + * 0: default (the driver will decide when to dither) + * 1: enabled (the driver will always dither when possible) + * 2: disabled (the driver will never dither) + */ + +#define NV_CTRL_FLATPANEL_DITHERING 3 /* RWD */ +#define NV_CTRL_FLATPANEL_DITHERING_DEFAULT 0 +#define NV_CTRL_FLATPANEL_DITHERING_ENABLED 1 +#define NV_CTRL_FLATPANEL_DITHERING_DISABLED 2 + + +/* + * NV_CTRL_DIGITAL_VIBRANCE - sets the digital vibrance level for the + * specified display device. + */ + +#define NV_CTRL_DIGITAL_VIBRANCE 4 /* RWD */ + + +/* + * NV_CTRL_BUS_TYPE - returns the Bus type through which the GPU + * driving the specified X screen is connected to the computer. + */ + +#define NV_CTRL_BUS_TYPE 5 /* R-- */ +#define NV_CTRL_BUS_TYPE_AGP 0 +#define NV_CTRL_BUS_TYPE_PCI 1 +#define NV_CTRL_BUS_TYPE_PCI_EXPRESS 2 + + +/* + * NV_CTRL_VIDEO_RAM - returns the amount of video ram on the GPU + * driving the specified X screen. + */ + +#define NV_CTRL_VIDEO_RAM 6 /* R-- */ + + +/* + * NV_CTRL_IRQ - returns the interrupt request line used by the GPU + * driving the specified X screen. + */ + +#define NV_CTRL_IRQ 7 /* R-- */ + + +/* + * NV_CTRL_OPERATING_SYSTEM - returns the operating system on which + * the X server is running. + */ + +#define NV_CTRL_OPERATING_SYSTEM 8 /* R-- */ +#define NV_CTRL_OPERATING_SYSTEM_LINUX 0 +#define NV_CTRL_OPERATING_SYSTEM_FREEBSD 1 + + +/* + * NV_CTRL_SYNC_TO_VBLANK - enables sync to vblank for OpenGL clients. + * This setting is only applied to OpenGL clients that are started + * after this setting is applied. + */ + +#define NV_CTRL_SYNC_TO_VBLANK 9 /* RW- */ +#define NV_CTRL_SYNC_TO_VBLANK_OFF 0 +#define NV_CTRL_SYNC_TO_VBLANK_ON 1 + + +/* + * NV_CTRL_LOG_ANISO - enables anisotropic filtering for OpenGL + * clients; on some NVIDIA hardware, this can only be enabled or + * disabled; on other hardware different levels of anisotropic + * filtering can be specified. This setting is only applied to OpenGL + * clients that are started after this setting is applied. + */ + +#define NV_CTRL_LOG_ANISO 10 /* RW- */ + + +/* + * NV_CTRL_FSAA_MODE - the FSAA setting for OpenGL clients; possible + * FSAA modes: + * + * NV_CTRL_FSAA_MODE_2x "2x Bilinear Multisampling" + * NV_CTRL_FSAA_MODE_2x_5t "2x Quincunx Multisampling" + * NV_CTRL_FSAA_MODE_15x15 "1.5 x 1.5 Supersampling" + * NV_CTRL_FSAA_MODE_2x2 "2 x 2 Supersampling" + * NV_CTRL_FSAA_MODE_4x "4x Bilinear Multisampling" + * NV_CTRL_FSAA_MODE_4x_9t "4x Gaussian Multisampling" + * NV_CTRL_FSAA_MODE_8x "2x Bilinear Multisampling by 4x Supersampling" + * NV_CTRL_FSAA_MODE_16x "4x Bilinear Multisampling by 4x Supersampling" + * + * This setting is only applied to OpenGL clients that are started + * after this setting is applied. + */ + +#define NV_CTRL_FSAA_MODE 11 /* RW- */ +#define NV_CTRL_FSAA_MODE_NONE 0 +#define NV_CTRL_FSAA_MODE_2x 1 +#define NV_CTRL_FSAA_MODE_2x_5t 2 +#define NV_CTRL_FSAA_MODE_15x15 3 +#define NV_CTRL_FSAA_MODE_2x2 4 +#define NV_CTRL_FSAA_MODE_4x 5 +#define NV_CTRL_FSAA_MODE_4x_9t 6 +#define NV_CTRL_FSAA_MODE_8x 7 +#define NV_CTRL_FSAA_MODE_16x 8 + + +/* + * NV_CTRL_TEXTURE_SHARPEN - enables texture sharpening for OpenGL + * clients. This setting is only applied to OpenGL clients that are + * started after this setting is applied. + */ + +#define NV_CTRL_TEXTURE_SHARPEN 12 /* RW- */ +#define NV_CTRL_TEXTURE_SHARPEN_OFF 0 +#define NV_CTRL_TEXTURE_SHARPEN_ON 1 + + +/* + * NV_CTRL_UBB - returns whether UBB is enabled for the specified X + * screen. + */ + +#define NV_CTRL_UBB 13 /* R-- */ +#define NV_CTRL_UBB_OFF 0 +#define NV_CTRL_UBB_ON 1 + + +/* + * NV_CTRL_OVERLAY - returns whether the RGB overlay is enabled for + * the specified X screen. + */ + +#define NV_CTRL_OVERLAY 14 /* R-- */ +#define NV_CTRL_OVERLAY_OFF 0 +#define NV_CTRL_OVERLAY_ON 1 + + +/* + * NV_CTRL_STEREO - returns whether stereo (and what type) is enabled + * for the specified X screen. + */ + +#define NV_CTRL_STEREO 16 /* R-- */ +#define NV_CTRL_STEREO_OFF 0 +#define NV_CTRL_STEREO_DDC 1 +#define NV_CTRL_STEREO_BLUELINE 2 +#define NV_CTRL_STEREO_DIN 3 +#define NV_CTRL_STEREO_TWINVIEW 4 + + +/* + * NV_CTRL_EMULATE - controls OpenGL software emulation of future + * NVIDIA GPUs. + */ + +#define NV_CTRL_EMULATE 17 /* RW- */ +#define NV_CTRL_EMULATE_NONE 0 + + +/* + * NV_CTRL_TWINVIEW - returns whether TwinView is enabled for the + * specified X screen. + */ + +#define NV_CTRL_TWINVIEW 18 /* R-- */ +#define NV_CTRL_TWINVIEW_NOT_ENABLED 0 +#define NV_CTRL_TWINVIEW_ENABLED 1 + + +/* + * NV_CTRL_CONNECTED_DISPLAYS - returns a display mask indicating what + * display devices are connected to the GPU driving the specified X + * screen. + */ + +#define NV_CTRL_CONNECTED_DISPLAYS 19 /* R-- */ + + +/* + * NV_CTRL_ENABLED_DISPLAYS - returns a display mask indicating what + * display devices are enabled for use on the specified X screen. + */ + +#define NV_CTRL_ENABLED_DISPLAYS 20 /* R-- */ + +/**************************************************************************/ +/* + * Integer attributes specific to configuring FrameLock on boards that + * support it. + */ + + +/* + * NV_CTRL_FRAMELOCK - returns whether this X screen supports + * FrameLock. All of the other FrameLock attributes are only + * applicable if NV_CTRL_FRAMELOCK is _SUPPORTED. + */ + +#define NV_CTRL_FRAMELOCK 21 /* R-- */ +#define NV_CTRL_FRAMELOCK_NOT_SUPPORTED 0 +#define NV_CTRL_FRAMELOCK_SUPPORTED 1 + + +/* + * NV_CTRL_FRAMELOCK_MASTER - get/set whether this X screen is the + * FrameLock master for the entire sync group. Note that only one + * node in the sync group should be configured as the master. + */ + +#define NV_CTRL_FRAMELOCK_MASTER 22 /* RW- */ +#define NV_CTRL_FRAMELOCK_MASTER_FALSE 0 +#define NV_CTRL_FRAMELOCK_MASTER_TRUE 1 + + +/* + * NV_CTRL_FRAMELOCK_POLARITY - sync either to the rising edge of the + * framelock pulse, or both the rising and falling edges of the + * framelock pulse. + */ + +#define NV_CTRL_FRAMELOCK_POLARITY 23 /* RW- */ +#define NV_CTRL_FRAMELOCK_POLARITY_RISING_EDGE 0x1 +#define NV_CTRL_FRAMELOCK_POLARITY_BOTH_EDGES 0x3 + + +/* + * NV_CTRL_FRAMELOCK_SYNC_DELAY - delay between the framelock pulse + * and the GPU sync. This is an 11 bit value which is multipled by + * 7.81 to determine the sync delay in microseconds. + */ + +#define NV_CTRL_FRAMELOCK_SYNC_DELAY 24 /* RW- */ +#define NV_CTRL_FRAMELOCK_SYNC_DELAY_MAX 2047 +#define NV_CTRL_FRAMELOCK_SYNC_DELAY_FACTOR 7.81 + +/* + * NV_CTRL_FRAMELOCK_SYNC_INTERVAL - how many house sync pulses + * between the FrameLock sync generation (0 == sync every house sync); + * this only applies to the master when receiving house sync. + */ + +#define NV_CTRL_FRAMELOCK_SYNC_INTERVAL 25 /* RW- */ + + +/* + * NV_CTRL_FRAMELOCK_PORT0_STATUS - status of the rj45 port0. + */ + +#define NV_CTRL_FRAMELOCK_PORT0_STATUS 26 /* R-- */ +#define NV_CTRL_FRAMELOCK_PORT0_STATUS_INPUT 0 +#define NV_CTRL_FRAMELOCK_PORT0_STATUS_OUTPUT 1 + + +/* + * NV_CTRL_FRAMELOCK_PORT1_STATUS - status of the rj45 port1. + */ + +#define NV_CTRL_FRAMELOCK_PORT1_STATUS 27 /* R-- */ +#define NV_CTRL_FRAMELOCK_PORT1_STATUS_INPUT 0 +#define NV_CTRL_FRAMELOCK_PORT1_STATUS_OUTPUT 1 + + +/* + * NV_CTRL_FRAMELOCK_HOUSE_STATUS - status of the house input (the BNC + * connector). + */ + +#define NV_CTRL_FRAMELOCK_HOUSE_STATUS 28 /* R-- */ +#define NV_CTRL_FRAMELOCK_HOUSE_STATUS_NOT_DETECTED 0 +#define NV_CTRL_FRAMELOCK_HOUSE_STATUS_DETECTED 1 + + +/* + * NV_CTRL_FRAMELOCK_SYNC - enable/disable the syncing of the + * specified display devices to the FrameLock pulse. + */ + +#define NV_CTRL_FRAMELOCK_SYNC 29 /* RWD */ +#define NV_CTRL_FRAMELOCK_SYNC_DISABLE 0 +#define NV_CTRL_FRAMELOCK_SYNC_ENABLE 1 + + +/* + * NV_CTRL_FRAMELOCK_SYNC_READY - reports whether a slave FrameLock + * board is receiving sync (regardless of whether or not any display + * devices are using the sync). + */ + +#define NV_CTRL_FRAMELOCK_SYNC_READY 30 /* R-- */ +#define NV_CTRL_FRAMELOCK_SYNC_READY_FALSE 0 +#define NV_CTRL_FRAMELOCK_SYNC_READY_TRUE 1 + + +/* + * NV_CTRL_FRAMELOCK_STEREO_SYNC - this indicates that the GPU stereo + * signal is in sync with the framelock stereo signal. + */ + +#define NV_CTRL_FRAMELOCK_STEREO_SYNC 31 /* R-- */ +#define NV_CTRL_FRAMELOCK_STEREO_SYNC_FALSE 0 +#define NV_CTRL_FRAMELOCK_STEREO_SYNC_TRUE 1 + + +/* + * NV_CTRL_FRAMELOCK_TEST_SIGNAL - to test the connections in the sync + * group, tell the master to enable a test signal, then query port[01] + * status and sync_ready on all slaves. When done, tell the master to + * disable the test signal. Test signal should only be manipulated + * while NV_CTRL_FRAMELOCK_SYNC is enabled. + * + * The TEST_SIGNAL is also used to reset the Universal Frame Count (as + * returned by the glXQueryFrameCountNV() function in the + * GLX_NV_swap_group extension). Note: for best accuracy of the + * Universal Frame Count, it is recommended to toggle the TEST_SIGNAL + * on and off after enabling FrameLock. + */ + +#define NV_CTRL_FRAMELOCK_TEST_SIGNAL 32 /* RW- */ +#define NV_CTRL_FRAMELOCK_TEST_SIGNAL_DISABLE 0 +#define NV_CTRL_FRAMELOCK_TEST_SIGNAL_ENABLE 1 + + +/* + * NV_CTRL_FRAMELOCK_ETHERNET_DETECTED - The FrameLock boards are + * cabled together using regular cat5 cable, connecting to rj45 ports + * on the backplane of the card. There is some concern that users may + * think these are ethernet ports and connect them to a + * router/hub/etc. The hardware can detect this and will shut off to + * prevent damage (either to itself or to the router). + * NV_CTRL_FRAMELOCK_ETHERNET_DETECTED may be called to find out if + * ethernet is connected to one of the rj45 ports. An appropriate + * error message should then be displayed. The _PORT0 and PORT1 + * values may be or'ed together. + */ + +#define NV_CTRL_FRAMELOCK_ETHERNET_DETECTED 33 /* R-- */ +#define NV_CTRL_FRAMELOCK_ETHERNET_DETECTED_NONE 0 +#define NV_CTRL_FRAMELOCK_ETHERNET_DETECTED_PORT0 0x1 +#define NV_CTRL_FRAMELOCK_ETHERNET_DETECTED_PORT1 0x2 + + +/* + * NV_CTRL_FRAMELOCK_VIDEO_MODE - get/set the video mode of the house + * input. + */ + +#define NV_CTRL_FRAMELOCK_VIDEO_MODE 34 /* RW- */ +#define NV_CTRL_FRAMELOCK_VIDEO_MODE_NONE 0 +#define NV_CTRL_FRAMELOCK_VIDEO_MODE_TTL 1 +#define NV_CTRL_FRAMELOCK_VIDEO_MODE_NTSCPALSECAM 2 +#define NV_CTRL_FRAMELOCK_VIDEO_MODE_HDTV 3 + +/* + * During FRAMELOCK bring-up, the above values were redefined to + * these: + */ + +#define NV_CTRL_FRAMELOCK_VIDEO_MODE_COMPOSITE_AUTO 0 +#define NV_CTRL_FRAMELOCK_VIDEO_MODE_TTL 1 +#define NV_CTRL_FRAMELOCK_VIDEO_MODE_COMPOSITE_BI_LEVEL 2 +#define NV_CTRL_FRAMELOCK_VIDEO_MODE_COMPOSITE_TRI_LEVEL 3 + + +/* + * NV_CTRL_FRAMELOCK_SYNC_RATE - this is the refresh rate that the + * framelock board is sending to the GPU, in milliHz. + */ + +#define NV_CTRL_FRAMELOCK_SYNC_RATE 35 /* R-- */ + + + +/**************************************************************************/ + +/* + * NV_CTRL_FORCE_GENERIC_CPU - inhibit the use of CPU specific + * features such as MMX, SSE, or 3DNOW! for OpenGL clients; this + * option may result in performance loss, but may be useful in + * conjunction with software such as the Valgrind memory debugger. + * This setting is only applied to OpenGL clients that are started + * after this setting is applied. + */ + +#define NV_CTRL_FORCE_GENERIC_CPU 37 /* RW- */ +#define NV_CTRL_FORCE_GENERIC_CPU_DISABLE 0 +#define NV_CTRL_FORCE_GENERIC_CPU_ENABLE 1 + + +/* + * NV_CTRL_OPENGL_AA_LINE_GAMMA - for OpenGL clients, allow + * Gamma-corrected antialiased lines to consider variances in the + * color display capabilities of output devices when rendering smooth + * lines. Only available on recent Quadro GPUs. This setting is only + * applied to OpenGL clients that are started after this setting is + * applied. + */ + +#define NV_CTRL_OPENGL_AA_LINE_GAMMA 38 /* RW- */ +#define NV_CTRL_OPENGL_AA_LINE_GAMMA_DISABLE 0 +#define NV_CTRL_OPENGL_AA_LINE_GAMMA_ENABLE 1 + + +/* + * NV_CTRL_FRAMELOCK_TIMING - this is TRUE when the framelock board is + * receiving timing input. + */ + +#define NV_CTRL_FRAMELOCK_TIMING 39 /* RW- */ +#define NV_CTRL_FRAMELOCK_TIMING_FALSE 0 +#define NV_CTRL_FRAMELOCK_TIMING_TRUE 1 + +/* + * NV_CTRL_FLIPPING_ALLOWED - when TRUE, OpenGL will swap by flipping + * when possible; when FALSE, OpenGL will alway swap by blitting. XXX + * can this be enabled dynamically? + */ + +#define NV_CTRL_FLIPPING_ALLOWED 40 /* RW- */ +#define NV_CTRL_FLIPPING_ALLOWED_FALSE 0 +#define NV_CTRL_FLIPPING_ALLOWED_TRUE 1 + +/* + * NV_CTRL_ARCHITECTURE - returns the architecture on which the X server is + * running. + */ + +#define NV_CTRL_ARCHITECTURE 41 /* R-- */ +#define NV_CTRL_ARCHITECTURE_X86 0 +#define NV_CTRL_ARCHITECTURE_X86_64 1 +#define NV_CTRL_ARCHITECTURE_IA64 2 + + +/* + * NV_CTRL_TEXTURE_CLAMPING - texture clamping mode in OpenGL. By + * default, NVIDIA's OpenGL implementation uses CLAMP_TO_EDGE, which + * is not strictly conformant, but some applications rely on the + * non-conformant behavior, and not all GPUs support conformant + * texture clamping in hardware. _SPEC forces OpenGL texture clamping + * to be conformant, but may introduce slower performance on older + * GPUS, or incorrect texture clamping in certain applications. + */ + +#define NV_CTRL_TEXTURE_CLAMPING 42 /* RW- */ +#define NV_CTRL_TEXTURE_CLAMPING_EDGE 0 +#define NV_CTRL_TEXTURE_CLAMPING_SPEC 1 + + + +#define NV_CTRL_CURSOR_SHADOW 43 /* RW- */ +#define NV_CTRL_CURSOR_SHADOW_DISABLE 0 +#define NV_CTRL_CURSOR_SHADOW_ENABLE 1 + +#define NV_CTRL_CURSOR_SHADOW_ALPHA 44 /* RW- */ +#define NV_CTRL_CURSOR_SHADOW_RED 45 /* RW- */ +#define NV_CTRL_CURSOR_SHADOW_GREEN 46 /* RW- */ +#define NV_CTRL_CURSOR_SHADOW_BLUE 47 /* RW- */ + +#define NV_CTRL_CURSOR_SHADOW_X_OFFSET 48 /* RW- */ +#define NV_CTRL_CURSOR_SHADOW_Y_OFFSET 49 /* RW- */ + + + +/* + * When Application Control for FSAA is enabled, then what the + * application requests is used, and NV_CTRL_FSAA_MODE is ignored. If + * this is disabled, then any application setting is overridden with + * NV_CTRL_FSAA_MODE + */ + +#define NV_CTRL_FSAA_APPLICATION_CONTROLLED 50 /* RW- */ +#define NV_CTRL_FSAA_APPLICATION_CONTROLLED_ENABLED 1 +#define NV_CTRL_FSAA_APPLICATION_CONTROLLED_DISABLED 0 + + +/* + * When Application Control for LogAniso is enabled, then what the + * application requests is used, and NV_CTRL_LOG_ANISO is ignored. If + * this is disabled, then any application setting is overridden with + * NV_CTRL_LOG_ANISO + */ + +#define NV_CTRL_LOG_ANISO_APPLICATION_CONTROLLED 51 /* RW- */ +#define NV_CTRL_LOG_ANISO_APPLICATION_CONTROLLED_ENABLED 1 +#define NV_CTRL_LOG_ANISO_APPLICATION_CONTROLLED_DISABLED 0 + + +/* + * IMAGE_SHARPENING adjusts the sharpness of the display's image + * quality by amplifying high frequency content. Valid values will + * normally be in the range [0,32). Only available on GeForceFX or + * newer. + */ + +#define NV_CTRL_IMAGE_SHARPENING 52 /* RWD */ + + +/* + * NV_CTRL_TV_OVERSCAN adjusts the amount of overscan on the specified + * display device. + */ + +#define NV_CTRL_TV_OVERSCAN 53 /* RWD */ + + +/* + * NV_CTRL_TV_FLICKER_FILTER adjusts the amount of flicker filter on + * the specified display device. + */ + +#define NV_CTRL_TV_FLICKER_FILTER 54 /* RWD */ + + +/* + * NV_CTRL_TV_BRIGHTNESS adjusts the amount of brightness on the + * specified display device. + */ + +#define NV_CTRL_TV_BRIGHTNESS 55 /* RWD */ + + +/* + * NV_CTRL_TV_HUE adjusts the amount of hue on the specified display + * device. + */ + +#define NV_CTRL_TV_HUE 56 /* RWD */ + + +/* + * NV_CTRL_TV_CONTRAST adjusts the amount of contrast on the specified + * display device. + */ + +#define NV_CTRL_TV_CONTRAST 57 /* RWD */ + + +/* + * NV_CTRL_TV_SATURATION adjusts the amount of saturation on the + * specified display device. + */ + +#define NV_CTRL_TV_SATURATION 58 /* RWD */ + + +/* + * NV_CTRL_TV_RESET_SETTINGS - this write-only attribute can be used + * to request that all TV Settings be reset to their default values; + * typical usage would be that this attribute be sent, and then all + * the TV attributes be queried to retrieve their new values. + */ + +#define NV_CTRL_TV_RESET_SETTINGS 59 /* -WD */ + + +/* + * NV_CTRL_GPU_CORE_TEMPERATURE reports the current core temperature + * of the GPU driving the X screen. + */ + +#define NV_CTRL_GPU_CORE_TEMPERATURE 60 /* R-- */ + + +/* + * NV_CTRL_GPU_CORE_THRESHOLD reports the current GPU core slowdown + * threshold temperature, NV_CTRL_GPU_DEFAULT_CORE_THRESHOLD and + * NV_CTRL_GPU_MAX_CORE_THRESHOLD report the default and MAX core + * slowdown threshold temperatures. + * + * NV_CTRL_GPU_CORE_THRESHOLD reflects the temperature at which the + * GPU is throttled to prevent overheating. + */ + +#define NV_CTRL_GPU_CORE_THRESHOLD 61 /* R-- */ +#define NV_CTRL_GPU_DEFAULT_CORE_THRESHOLD 62 /* R-- */ +#define NV_CTRL_GPU_MAX_CORE_THRESHOLD 63 /* R-- */ + + +/* + * NV_CTRL_AMBIENT_TEMPERATURE reports the current temperature in the + * immediate neighbourhood of the GPU driving the X screen. + */ + +#define NV_CTRL_AMBIENT_TEMPERATURE 64 /* R-- */ + + +/* + * NV_CTRL_PBUFFER_SCANOUT_SUPPORTED - returns whether this X screen + * supports scanout of FP pbuffers; + * + * if this screen does not support PBUFFER_SCANOUT, then all other + * PBUFFER_SCANOUT attributes are unavailable. + */ + +#define NV_CTRL_PBUFFER_SCANOUT_SUPPORTED 65 /* R-- */ +#define NV_CTRL_PBUFFER_SCANOUT_FALSE 0 +#define NV_CTRL_PBUFFER_SCANOUT_TRUE 1 + +/* + * NV_CTRL_PBUFFER_SCANOUT_XID indicates the XID of the pbuffer used for + * scanout. + */ +#define NV_CTRL_PBUFFER_SCANOUT_XID 66 /* RW- */ + +#define NV_CTRL_LAST_ATTRIBUTE NV_CTRL_PBUFFER_SCANOUT_XID + +/**************************************************************************/ + +/* + * String Attributes: + */ + + +/* + * NV_CTRL_STRING_PRODUCT_NAME - the GPU product name on which the + * specified X screen is running. + */ + +#define NV_CTRL_STRING_PRODUCT_NAME 0 /* R-- */ + + +/* + * NV_CTRL_STRING_VBIOS_VERSION - the video bios version on the GPU on + * which the specified X screen is running. + */ + +#define NV_CTRL_STRING_VBIOS_VERSION 1 /* R-- */ + + +/* + * NV_CTRL_STRING_NVIDIA_DRIVER_VERSION - string representation of the + * NVIDIA driver version number for the NVIDIA X driver in use. + */ + +#define NV_CTRL_STRING_NVIDIA_DRIVER_VERSION 3 /* R-- */ + + +/* + * NV_CTRL_STRING_DISPLAY_DEVICE_NAME - name of the display device + * specified in the display_mask argument. + */ + +#define NV_CTRL_STRING_DISPLAY_DEVICE_NAME 4 /* R-D */ + + +/* + * NV_CTRL_STRING_TV_ENCODER_NAME - name of the TV encoder used by the + * specified display device; only valid if the display device is a TV. + */ + +#define NV_CTRL_STRING_TV_ENCODER_NAME 5 /* R-D */ + +#define NV_CTRL_STRING_LAST_ATTRIBUTE NV_CTRL_STRING_TV_ENCODER_NAME + + + +/**************************************************************************/ +/* + * CTRLAttributeValidValuesRec - + * + * structure and related defines used by + * XNVCTRLQueryValidAttributeValues() to describe the valid values of + * a particular attribute. The type field will be one of: + * + * ATTRIBUTE_TYPE_INTEGER : the attribute is an integer value; there + * is no fixed range of valid values. + * + * ATTRIBUTE_TYPE_BITMASK : the attribute is an integer value, + * interpretted as a bitmask. + * + * ATTRIBUTE_TYPE_BOOL : the attribute is a boolean, valid values are + * either 1 (on/true) or 0 (off/false). + * + * ATTRIBUTE_TYPE_RANGE : the attribute can have any integer value + * between NVCTRLAttributeValidValues.u.range.min and + * NVCTRLAttributeValidValues.u.range.max (inclusive). + * + * ATTRIBUTE_TYPE_INT_BITS : the attribute can only have certain + * integer values, indicated by which bits in + * NVCTRLAttributeValidValues.u.bits.ints are on (for example: if bit + * 0 is on, then 0 is a valid value; if bit 5 is on, then 5 is a valid + * value, etc). This is useful for attributes like NV_CTRL_FSAA_MODE, + * which can only have certain values, depending on GPU. + * + * + * The permissions field of NVCTRLAttributeValidValuesRec is a bitmask + * that may contain: + * + * ATTRIBUTE_TYPE_READ + * ATTRIBUTE_TYPE_WRITE + * ATTRIBUTE_TYPE_DISPLAY + * + * See 'Key to Integer Attribute "Permissions"' at the top of this + * file for a description of what these three permission bits mean. + */ + +#define ATTRIBUTE_TYPE_UNKNOWN 0 +#define ATTRIBUTE_TYPE_INTEGER 1 +#define ATTRIBUTE_TYPE_BITMASK 2 +#define ATTRIBUTE_TYPE_BOOL 3 +#define ATTRIBUTE_TYPE_RANGE 4 +#define ATTRIBUTE_TYPE_INT_BITS 5 + +#define ATTRIBUTE_TYPE_READ 0x1 +#define ATTRIBUTE_TYPE_WRITE 0x2 +#define ATTRIBUTE_TYPE_DISPLAY 0x4 + +typedef struct _NVCTRLAttributeValidValues { + int type; + union { + struct { + int min; + int max; + } range; + struct { + unsigned int ints; + } bits; + } u; + unsigned int permissions; +} NVCTRLAttributeValidValuesRec; + + + +#define ATTRIBUTE_CHANGED_EVENT 0 + + +#endif /* __NVCTRL_H */ diff --git a/ksim/monitors/lm_sensors/NVCtrlLib.h b/ksim/monitors/lm_sensors/NVCtrlLib.h new file mode 100644 index 0000000..8d9cec4 --- /dev/null +++ b/ksim/monitors/lm_sensors/NVCtrlLib.h @@ -0,0 +1,184 @@ +#ifndef __NVCTRLLIB_H +#define __NVCTRLLIB_H + +#include "NVCtrl.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +/* + * XNVCTRLQueryExtension - + * + * Returns True if the extension exists, returns False otherwise. + * event_basep and error_basep are the extension event and error + * bases. Currently, no extension specific errors or events are + * defined. + */ + +Bool XNVCTRLQueryExtension ( + Display *dpy, + int *event_basep, + int *error_basep +); + +/* + * XNVCTRLQueryVersion - + * + * Returns True if the extension exists, returns False otherwise. + * major and minor are the extension's major and minor version + * numbers. + */ + +Bool XNVCTRLQueryVersion ( + Display *dpy, + int *major, + int *minor +); + + +/* + * XNVCTRLIsNvScreen + * + * Returns True is the specified screen is controlled by the NVIDIA + * driver. Returns False otherwise. + */ + +Bool XNVCTRLIsNvScreen ( + Display *dpy, + int screen +); + +/* + * XNVCTRLSetAttribute - + * + * Sets the attribute to the given value. The attributes and their + * possible values are listed in NVCtrl.h. + * + * Not all attributes require the display_mask parameter; see + * NVCtrl.h for details. + * + * Possible errors: + * BadValue - The screen or attribute doesn't exist. + * BadMatch - The NVIDIA driver is not present on that screen. + */ + +void XNVCTRLSetAttribute ( + Display *dpy, + int screen, + unsigned int display_mask, + unsigned int attribute, + int value +); + +/* + * XNVCTRLQueryAttribute - + * + * Returns True if the attribute exists. Returns False otherwise. + * If XNVCTRLQueryAttribute returns True, value will contain the + * value of the specified attribute. + * + * Not all attributes require the display_mask parameter; see + * NVCtrl.h for details. + * + * Possible errors: + * BadValue - The screen doesn't exist. + * BadMatch - The NVIDIA driver is not present on that screen. + */ + + +Bool XNVCTRLQueryAttribute ( + Display *dpy, + int screen, + unsigned int display_mask, + unsigned int attribute, + int *value +); + +/* + * XNVCTRLQueryStringAttribute - + * + * Returns True if the attribute exists. Returns False otherwise. + * If XNVCTRLQueryStringAttribute returns True, *ptr will point to an + * allocated string containing the string attribute requested. It is + * the caller's responsibility to free the string when done. + * + * Possible errors: + * BadValue - The screen doesn't exist. + * BadMatch - The NVIDIA driver is not present on that screen. + * BadAlloc - Insufficient resources to fulfill the request. + */ + +Bool XNVCTRLQueryStringAttribute ( + Display *dpy, + int screen, + unsigned int display_mask, + unsigned int attribute, + char **ptr +); + +/* + * XNVCTRLQueryValidAttributeValues - + * + * Returns True if the attribute exists. Returns False otherwise. If + * XNVCTRLQueryValidAttributeValues returns True, values will indicate + * the valid values for the specified attribute; see the description + * of NVCTRLAttributeValidValues in NVCtrl.h. + */ + +Bool XNVCTRLQueryValidAttributeValues ( + Display *dpy, + int screen, + unsigned int display_mask, + unsigned int attribute, + NVCTRLAttributeValidValuesRec *values +); + +/* + * XNVCtrlSelectNotify - + * + * This enables/disables receiving of NV-CONTROL events. The type + * specifies the type of event to enable (currently, the only type is + * ATTRIBUTE_CHANGED_EVENT); onoff controls whether receiving this + * type of event should be enabled (True) or disabled (False). + * + * Returns True if successful, or False if the screen is not + * controlled by the NVIDIA driver. + */ + +Bool XNVCtrlSelectNotify ( + Display *dpy, + int screen, + int type, + Bool onoff +); + + + +/* + * XNVCtrlEvent structure + */ + +typedef struct { + int type; + unsigned long serial; + Bool send_event; /* always FALSE, we don't allow send_events */ + Display *display; + Time time; + int screen; + unsigned int display_mask; + unsigned int attribute; + int value; +} XNVCtrlAttributeChangedEvent; + +typedef union { + int type; + XNVCtrlAttributeChangedEvent attribute_changed; + long pad[24]; +} XNVCtrlEvent; + +#if defined(__cplusplus) +} +#endif + +#endif /* __NVCTRLLIB_H */ diff --git a/ksim/monitors/lm_sensors/ksimsensors.cpp b/ksim/monitors/lm_sensors/ksimsensors.cpp new file mode 100644 index 0000000..e63f5cf --- /dev/null +++ b/ksim/monitors/lm_sensors/ksimsensors.cpp @@ -0,0 +1,189 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#include "ksimsensors.h" +#include "ksimsensors.moc" + +#include <kdebug.h> +#include <kapplication.h> +#include <klocale.h> +#include <kaboutapplication.h> +#include <kaboutdata.h> +#include <kconfig.h> + +#include <qlayout.h> + +#include <label.h> +#include <themetypes.h> +#include "sensorsconfig.h" +#include "sensorbase.h" + +KSIM_INIT_PLUGIN(PluginModule) + +PluginModule::PluginModule(const char *name) + : KSim::PluginObject(name) +{ + setConfigFileName(instanceName()); +} + +PluginModule::~PluginModule() +{ +} + +KSim::PluginView *PluginModule::createView(const char *className) +{ + return new SensorsView(this, className); +} + +KSim::PluginPage *PluginModule::createConfigPage(const char *className) +{ + return new SensorsConfig(this, className); +} + +void PluginModule::showAbout() +{ + QString version = kapp->aboutData()->version(); + + KAboutData aboutData(instanceName(), + I18N_NOOP("KSim Sensors Plugin"), version.latin1(), + I18N_NOOP("An lm_sensors plugin for KSim"), + KAboutData::License_GPL, "(C) 2001 Robbie Ward"); + + aboutData.addAuthor("Robbie Ward", I18N_NOOP("Author"), + "linuxphreak@gmx.co.uk"); + + KAboutApplication(&aboutData).exec(); +} + +SensorsView::SensorsView(KSim::PluginObject *parent, const char *name) + : DCOPObject("sensors"), KSim::PluginView(parent, name) +{ + config()->setGroup("Sensors"); + (new QVBoxLayout(this))->setAutoAdd(true); + + connect(SensorBase::self(), SIGNAL(updateSensors(const SensorList &)), + this, SLOT(updateSensors(const SensorList &))); + + insertSensors(); +} + +SensorsView::~SensorsView() +{ +} + +void SensorsView::reparseConfig() +{ + config()->setGroup("Sensors"); + bool displayFahrenheit = config()->readBoolEntry("displayFahrenheit", false); + int updateVal = config()->readNumEntry("sensorUpdateValue", 5); + SensorBase::self()->setDisplayFahrenheit(displayFahrenheit); + SensorBase::self()->setUpdateSpeed(updateVal * 1000); + + QString label; + QStringList names; + SensorItemList sensorItemList; + const SensorList &list = SensorBase::self()->sensorsList(); + + SensorList::ConstIterator it; + for (it = list.begin(); it != list.end(); ++it) { + config()->setGroup("Sensors"); + label = (*it).sensorType() + "/" + (*it).sensorName(); + names = QStringList::split(':', config()->readEntry(label)); + if (names[0] == "1") + sensorItemList.append(SensorItem((*it).sensorId(), names[1])); + } + + if (sensorItemList == m_sensorItemList) + return; + + m_sensorItemList.clear(); + m_sensorItemList = sensorItemList; + insertSensors(false); +} + +void SensorsView::insertSensors(bool createList) +{ + const SensorList &list = SensorBase::self()->sensorsList(); + + if (createList) { + QString label; + QStringList names; + + config()->setGroup("Sensors"); + bool displayFahrenheit = config()->readBoolEntry("displayFahrenheit", false); + int updateVal = config()->readNumEntry("sensorUpdateValue", 5); + SensorBase::self()->setDisplayFahrenheit(displayFahrenheit); + SensorBase::self()->setUpdateSpeed(updateVal * 1000); + + SensorList::ConstIterator it; + for (it = list.begin(); it != list.end(); ++it) { + label = (*it).sensorType() + "/" + (*it).sensorName(); + names = QStringList::split(':', config()->readEntry(label)); + if (names[0] == "1") + m_sensorItemList.append(SensorItem((*it).sensorId(), names[1])); + } + } + + SensorItemList::Iterator item; + for (item = m_sensorItemList.begin(); item != m_sensorItemList.end(); ++item) + (*item).setLabel(new KSim::Label(KSim::Types::None, this)); + + updateSensors(list); +} + +void SensorsView::updateSensors(const SensorList &sensorList) +{ + if (sensorList.isEmpty() || m_sensorItemList.isEmpty()) + return; + + SensorList::ConstIterator it; + for (it = sensorList.begin(); it != sensorList.end(); ++it) { + SensorItemList::Iterator item; + for (item = m_sensorItemList.begin(); item != m_sensorItemList.end(); ++item) { + if ((*item).id == (*it).sensorId()) { + if (!(*item).label->isVisible()) + (*item).label->show(); + + (*item).label->setText((*item).name + ": " + + (*it).sensorValue() + (*it).sensorUnit()); + } + } + } +} + +QString SensorsView::sensorValue(const QString &sensor, + const QString &label1) +{ + const SensorList &list = SensorBase::self()->sensorsList(); + config()->setGroup("Sensors"); + QStringList names = QStringList::split(':', + config()->readEntry(sensor + "/" + label1)); + + if (names[0] == "0" || list.isEmpty()) + return i18n("Sensor specified not found."); + + SensorList::ConstIterator it; + for (it = list.begin(); it != list.end(); ++it) { + if (sensor == (*it).sensorType() && label1 == (*it).sensorName()) { + return names[1] + QString(": ") + (*it).sensorValue() + (*it).sensorUnit(); + } + } + + return i18n("Sensor specified not found."); +} diff --git a/ksim/monitors/lm_sensors/ksimsensors.h b/ksim/monitors/lm_sensors/ksimsensors.h new file mode 100644 index 0000000..8446931 --- /dev/null +++ b/ksim/monitors/lm_sensors/ksimsensors.h @@ -0,0 +1,91 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#ifndef SENSORS_H +#define SENSORS_H + +#include <pluginmodule.h> +#include <label.h> +#include "ksimsensorsiface.h" + +class KConfig; +class SensorList; +class KInstance; + +/** + * This class is the lm_sensors monitor plugin + * + * @author Robbie Ward <linuxphreak@gmx.co.uk> + */ +class PluginModule : public KSim::PluginObject +{ + public: + PluginModule(const char *name); + ~PluginModule(); + + virtual KSim::PluginView *createView(const char *); + virtual KSim::PluginPage *createConfigPage(const char *); + + virtual void showAbout(); +}; + +class SensorsView : public KSim::PluginView, public KSimSensorsIface +{ + Q_OBJECT + public: + SensorsView(KSim::PluginObject *parent, const char *name); + ~SensorsView(); + + virtual void reparseConfig(); + virtual QString sensorValue(const QString &, const QString &); + + private slots: + void updateSensors(const SensorList &); + + private: + void insertSensors(bool createList = true); + + class SensorItem + { + public: + SensorItem() : id(-1), label(0) {} + SensorItem(int i, const QString &na) + : id(i), name(na), label(0) {} + ~SensorItem() { delete label; } + + bool operator==(const SensorItem &rhs) const + { + return (id == rhs.id && name == rhs.name); + } + + void setLabel(KSim::Label *lab) + { + delete label; + label = lab; + } + + int id; + QString name; + KSim::Label *label; + }; + + typedef QValueList<SensorItem> SensorItemList; + SensorItemList m_sensorItemList; +}; +#endif diff --git a/ksim/monitors/lm_sensors/ksimsensorsiface.h b/ksim/monitors/lm_sensors/ksimsensorsiface.h new file mode 100644 index 0000000..4bd50ce --- /dev/null +++ b/ksim/monitors/lm_sensors/ksimsensorsiface.h @@ -0,0 +1,33 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 - 2004 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#ifndef KSIMSENSORSIFACE_H +#define KSIMSENSORSIFACE_H + +#include <dcopobject.h> + +class KSimSensorsIface : virtual public DCOPObject +{ + K_DCOP + k_dcop: + virtual QString sensorValue(const QString &sensorType, + const QString &sensorName) = 0; +}; + +#endif // KSIMSENSORSIFACE_H diff --git a/ksim/monitors/lm_sensors/nv_control.h b/ksim/monitors/lm_sensors/nv_control.h new file mode 100644 index 0000000..d94ee95 --- /dev/null +++ b/ksim/monitors/lm_sensors/nv_control.h @@ -0,0 +1,205 @@ +/* + * Copyright (C) 2004 NVIDIA Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of Version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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 Version 2 + * of 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 + * + */ + +#ifndef __NVCONTROL_H +#define __NVCONTROL_H + +#define NV_CONTROL_ERRORS 0 +#define NV_CONTROL_EVENTS 1 +#define NV_CONTROL_NAME "NV-CONTROL" + +#define NV_CONTROL_MAJOR 1 +#define NV_CONTROL_MINOR 6 + +#define X_nvCtrlQueryExtension 0 +#define X_nvCtrlIsNv 1 +#define X_nvCtrlQueryAttribute 2 +#define X_nvCtrlSetAttribute 3 +#define X_nvCtrlQueryStringAttribute 4 +#define X_nvCtrlQueryValidAttributeValues 5 +#define X_nvCtrlSelectNotify 6 +#define X_nvCtrlLastRequest (X_nvCtrlSelectNotify + 1) + +typedef struct { + CARD8 reqType; + CARD8 nvReqType; + CARD16 length B16; +} xnvCtrlQueryExtensionReq; +#define sz_xnvCtrlQueryExtensionReq 4 + +typedef struct { + BYTE type; /* X_Reply */ + CARD8 padb1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD16 major B16; + CARD16 minor B16; + CARD32 padl4 B32; + CARD32 padl5 B32; + CARD32 padl6 B32; + CARD32 padl7 B32; + CARD32 padl8 B32; +} xnvCtrlQueryExtensionReply; +#define sz_xnvCtrlQueryExtensionReply 32 + +typedef struct { + CARD8 reqType; + CARD8 nvReqType; + CARD16 length B16; + CARD32 screen B32; +} xnvCtrlIsNvReq; +#define sz_xnvCtrlIsNvReq 8 + +typedef struct { + BYTE type; /* X_Reply */ + CARD8 padb1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 isnv B32; + CARD32 padl4 B32; + CARD32 padl5 B32; + CARD32 padl6 B32; + CARD32 padl7 B32; + CARD32 padl8 B32; +} xnvCtrlIsNvReply; +#define sz_xnvCtrlIsNvReply 32 + +typedef struct { + CARD8 reqType; + CARD8 nvReqType; + CARD16 length B16; + CARD32 screen B32; + CARD32 display_mask B32; + CARD32 attribute B32; +} xnvCtrlQueryAttributeReq; +#define sz_xnvCtrlQueryAttributeReq 16 + +typedef struct { + BYTE type; + BYTE pad0; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 flags B32; + INT32 value B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; +} xnvCtrlQueryAttributeReply; +#define sz_xnvCtrlQueryAttributeReply 32 + +typedef struct { + CARD8 reqType; + CARD8 nvReqType; + CARD16 length B16; + CARD32 screen B32; + CARD32 display_mask B32; + CARD32 attribute B32; + INT32 value B32; +} xnvCtrlSetAttributeReq; +#define sz_xnvCtrlSetAttributeReq 20 + +typedef struct { + CARD8 reqType; + CARD8 nvReqType; + CARD16 length B16; + CARD32 screen B32; + CARD32 display_mask B32; + CARD32 attribute B32; +} xnvCtrlQueryStringAttributeReq; +#define sz_xnvCtrlQueryStringAttributeReq 16 + +/* + * CtrlQueryStringAttribute reply struct + * n indicates the length of the string. + */ +typedef struct { + BYTE type; + BYTE pad0; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 flags B32; + CARD32 n B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; +} xnvCtrlQueryStringAttributeReply; +#define sz_xnvCtrlQueryStringAttributeReply 32 + +typedef struct { + CARD8 reqType; + CARD8 nvReqType; + CARD16 length B16; + CARD32 screen B32; + CARD32 display_mask B32; + CARD32 attribute B32; +} xnvCtrlQueryValidAttributeValuesReq; +#define sz_xnvCtrlQueryValidAttributeValuesReq 16 + +typedef struct { + BYTE type; + BYTE pad0; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 flags B32; + INT32 attr_type B32; + INT32 min B32; + INT32 max B32; + CARD32 bits B32; + CARD32 perms B32; +} xnvCtrlQueryValidAttributeValuesReply; +#define sz_xnvCtrlQueryValidAttributeValuesReply 32 + +typedef struct { + CARD8 reqType; + CARD8 nvReqType; + CARD16 length B16; + CARD32 screen B32; + CARD16 notifyType B16; + CARD16 onoff B16; +} xnvCtrlSelectNotifyReq; +#define sz_xnvCtrlSelectNotifyReq 12 + +typedef struct { + union { + struct { + BYTE type; + BYTE detail; + CARD16 sequenceNumber B16; + } u; + struct { + BYTE type; + BYTE detail; + CARD16 sequenceNumber B16; + Time time B32; + CARD32 screen B32; + CARD32 display_mask B32; + CARD32 attribute B32; + CARD32 value B32; + CARD32 pad0 B32; + CARD32 pad1 B32; + } attribute_changed; + } u; +} xnvctrlEvent; + + +#endif /* __NVCONTROL_H */ diff --git a/ksim/monitors/lm_sensors/sensorbase.cpp b/ksim/monitors/lm_sensors/sensorbase.cpp new file mode 100644 index 0000000..9ccb247 --- /dev/null +++ b/ksim/monitors/lm_sensors/sensorbase.cpp @@ -0,0 +1,254 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#include "sensorbase.h" +#include "sensorbase.moc" +#include <ksimconfig.h> + +#include <kdebug.h> +#include <klocale.h> +#include <qglobal.h> +#include <klibloader.h> +#include <kstandarddirs.h> +#include <kconfig.h> + +#include <qtimer.h> +#include <qfile.h> +#include <qregexp.h> + +#include <stdio.h> + +#include <X11/Xlib.h> + +#include "NVCtrl.h" +#include "NVCtrlLib.h" + +SensorBase *SensorBase::m_self = 0; +SensorBase *SensorBase::self() +{ + if (!m_self) { + m_self = new SensorBase; + qAddPostRoutine(cleanup); + } + + return m_self; +} + +SensorBase::SensorBase() : QObject() +{ + KSim::Config::config()->setGroup("Sensors"); + QCString sensorsName("libsensors.so"); + + QStringList sensorLocations = KSim::Config::config()->readListEntry("sensorLocations"); + + QStringList::ConstIterator it; + for (it = sensorLocations.begin(); it != sensorLocations.end(); ++it) { + if (QFile::exists((*it).local8Bit() + sensorsName)) { + m_libLocation = (*it).local8Bit() + sensorsName; + break; + } + } + + m_library = KLibLoader::self()->library(m_libLocation); + kdDebug(2003) << sensorsName << " location = " << m_libLocation << endl; + m_loaded = init(); + + { + int eventBase; + int errorBase; + m_hasNVControl = XNVCTRLQueryExtension(qt_xdisplay(), &eventBase, &errorBase) == True; + } + + m_updateTimer = new QTimer(this); + connect(m_updateTimer, SIGNAL(timeout()), SLOT(update())); +} + +SensorBase::~SensorBase() +{ + if (!m_libLocation.isNull()) { + if (m_cleanup) m_cleanup(); + KLibLoader::self()->unloadLibrary(m_libLocation); + } +} + +void SensorBase::setUpdateSpeed(uint speed) +{ + if (m_updateTimer->isActive()) + m_updateTimer->stop(); + + update(); // just to make sure the display is updated ASAP + + if (speed == 0) + return; + + m_updateTimer->start(speed); +} + +void SensorBase::update() +{ + if (!m_loaded) + return; + + m_sensorList.clear(); + const ChipName *chip; + int currentSensor = 0; + int sensor = 0; + + while ((chip = m_detectedChips(&sensor)) != NULL) { + int first = 0, second = 0; + const FeatureData *sFeature = 0; + while ((sFeature = m_allFeatures(*chip, &first, &second)) != NULL) { + if (sFeature->mapping == NoMapping) { + char *name; + double value; + m_label(*chip, sFeature->number, &name); + m_feature(*chip, sFeature->number, &value); + + float returnValue = formatValue(QString::fromUtf8(name), float(value)); + QString label = formatString(QString::fromUtf8(name), returnValue); + QString chipset = chipsetString(chip); + + m_sensorList.append(SensorInfo(currentSensor++, label, + QString::fromUtf8(name), QString::fromUtf8(chip->prefix), + chipset, sensorType(QString::fromLatin1(name)))); + } + } + } + + if (m_hasNVControl) { + int temp = 0; + if (XNVCTRLQueryAttribute(qt_xdisplay(), qt_xscreen(), 0 /* not used? */, NV_CTRL_GPU_CORE_TEMPERATURE, &temp)) { + QString name = QString::fromLatin1("GPU Temp"); + m_sensorList.append(SensorInfo(currentSensor++, QString::number(temp), + name, QString::null, QString::null, sensorType(name))); + } + + if (XNVCTRLQueryAttribute(qt_xdisplay(), qt_xscreen(), 0 /* not used? */, NV_CTRL_AMBIENT_TEMPERATURE, &temp)) { + QString name = QString::fromLatin1("GPU Ambient Temp"); + m_sensorList.append(SensorInfo(currentSensor++, QString::number(temp), + name, QString::null, QString::null, sensorType(name))); + } + + } + + emit updateSensors(m_sensorList); +} + +void SensorBase::cleanup() +{ + if (!m_self) + return; + + delete m_self; + m_self = 0; +} + +bool SensorBase::init() +{ + if (m_libLocation.isNull()) { + kdError() << "Unable to find libsensors.so" << endl; + return false; + } + + m_init = (Init)m_library->symbol("sensors_init"); + if (!m_init) + return false; + + m_error = (Error)m_library->symbol("sensors_strerror"); + if (!m_error) + return false; + + m_detectedChips = (GetDetectedChips *)m_library->symbol("sensors_get_detected_chips"); + m_allFeatures = (GetAllFeatures *)m_library->symbol("sensors_get_all_features"); + m_label = (Label)m_library->symbol("sensors_get_label"); + m_feature = (Feature)m_library->symbol("sensors_get_feature"); + + if (!m_detectedChips || !m_allFeatures || !m_label || !m_feature) + return false; + + m_cleanup = (Cleanup)m_library->symbol("sensors_cleanup"); + if (!m_cleanup) + return false; + + int res; + FILE *input; + + if ((input = fopen("/etc/sensors.conf", "r")) == 0) + return false; + + if ((res = m_init(input))) { + if (res == ProcError) { + kdError() << "There was an error reading the sensor information\n" + << "Make sure sensors.o and i2c-proc.o are loaded" << endl; + } + else { + kdError() << m_error(res) << endl; + } + + fclose(input); + return false; + } + + fclose(input); + + return true; +} + +QString SensorBase::sensorType(const QString &name) +{ + if (name.findRev("fan", -1, false) != -1) + return i18n("Rounds per minute", " RPM"); + + if (name.findRev("temp", -1, false) != -1) + if (SensorBase::fahrenheit()) + return QString::fromLatin1("°F"); + else + return QString::fromLatin1("°C"); + + if (name.findRev(QRegExp("[^\\+]?[^\\-]?V$")) != -1) + return i18n("Volt", "V"); + + return QString::null; +} + +QString SensorBase::chipsetString(const ChipName *c) +{ + QString data = QString::fromUtf8(c->prefix); + + if (c->bus == BusISA) + return QString().sprintf("%s-isa-%04x", data.utf8().data(), c->addr); + + return QString().sprintf("%s-i2c-%d-%02x", data.utf8().data(), c->bus, c->addr); +} + +float SensorBase::formatValue(const QString &label, float value) +{ + if (label.findRev("temp", -1, false) != -1) + return toFahrenheit(value); + + return value; +} + +QString SensorBase::formatString(const QString &label, float value) +{ + if (label.findRev("fan", -1, false) != -1) + return QString::number(value); + + return QString::number(value,'f',2); +} diff --git a/ksim/monitors/lm_sensors/sensorbase.h b/ksim/monitors/lm_sensors/sensorbase.h new file mode 100644 index 0000000..c819d48 --- /dev/null +++ b/ksim/monitors/lm_sensors/sensorbase.h @@ -0,0 +1,175 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#ifndef SENSORBASE_H +#define SENSORBASE_H + +#include <qobject.h> +#include <qvaluelist.h> +#include <qcstring.h> + +class QTimer; +class KLibrary; + +class SensorInfo +{ + public: + SensorInfo() {} + SensorInfo(int id, + const QString &sensorValue, + const QString &sensorName, + const QString &sensorType, + const QString &chipsetName, + const QString &sensorUnit) + : m_id(id), m_sensor(sensorValue), + m_sensorName(sensorName), + m_sensorType(sensorType), + m_chipsetName(chipsetName), + m_sensorUnit(sensorUnit) {} + + /** + * @return the sensor Id + */ + int sensorId() const { return m_id; } + /** + * @return the current value, eg: 5000 + */ + const QString &sensorValue() const { return m_sensor; } + /** + * @return the sensor name, eg: temp1, fan2 + */ + const QString &sensorName() const { return m_sensorName; } + /** + * @return the sensor type name, eg: w83782d + */ + const QString &sensorType() const { return m_sensorType; } + /** + * @return the chipset name, eg: w83782d-i2c-0-2d + */ + const QString &chipsetName() const { return m_chipsetName; } + /** + * @return the unit name, eg: RPM, °C or °F if display fahrenheit is enabled + */ + const QString &sensorUnit() const { return m_sensorUnit; } + + private: + int m_id; + QString m_sensor; + QString m_sensorName; + QString m_sensorType; + QString m_chipsetName; + QString m_sensorUnit; +}; + +class SensorList : public QValueList<SensorInfo> +{ + public: + SensorList() {} + SensorList(const SensorList &sensorList) + : QValueList<SensorInfo>(sensorList) {} + SensorList(const QValueList<SensorInfo> &sensorList) + : QValueList<SensorInfo>(sensorList) {} + SensorList(const SensorInfo &sensor) { append(sensor); } +}; + +class SensorBase : public QObject +{ + Q_OBJECT + public: + static SensorBase *self(); + + const SensorList &sensorsList() const { return m_sensorList; } + bool fahrenheit() { return m_fahrenheit; } + + signals: + void updateSensors(const SensorList&); + + public slots: + void setUpdateSpeed(uint); + void setDisplayFahrenheit(bool fah) { m_fahrenheit = fah; } + + private slots: + void update(); + + protected: + SensorBase(); + ~SensorBase(); + + private: + SensorBase(const SensorBase &); + SensorBase &operator=(const SensorBase &); + + static void cleanup(); + struct ChipName + { + char *prefix; + int bus; + int addr; + char *busname; + }; + + struct FeatureData + { + int number; + const char *name; + int mapping; + int unused; + int mode; + }; + + enum { ProcError=4, NoMapping=-1, BusISA=-1 }; + typedef void (*Cleanup)(); + typedef int (*Init)(FILE *); + typedef const char *(*Error)(int); + typedef const ChipName *(GetDetectedChips)(int *); + typedef const FeatureData *(GetAllFeatures)(ChipName, int *, int *); + typedef int (*Label)(ChipName, int, char **); + typedef int (*Feature)(ChipName, int, double *); + + bool init(); + float toFahrenheit(float value); + QString sensorType(const QString &name); + QString chipsetString(const ChipName *c); + float formatValue(const QString &label, float value); + QString formatString(const QString &label, float value); + + SensorList m_sensorList; + QTimer *m_updateTimer; + KLibrary *m_library; + QCString m_libLocation; + bool m_loaded; + bool m_fahrenheit; + + bool m_hasNVControl; + + Init m_init; + Error m_error; + GetDetectedChips *m_detectedChips; + GetAllFeatures *m_allFeatures; + Label m_label; + Feature m_feature; + Cleanup m_cleanup; + static SensorBase *m_self; +}; + +inline float SensorBase::toFahrenheit(float value) +{ + return fahrenheit() ? (value * (9.0F / 5.0F) + 32.0F) : value; +} +#endif // SENSORBASE_H diff --git a/ksim/monitors/lm_sensors/sensorsconfig.cpp b/ksim/monitors/lm_sensors/sensorsconfig.cpp new file mode 100644 index 0000000..6e2b4b3 --- /dev/null +++ b/ksim/monitors/lm_sensors/sensorsconfig.cpp @@ -0,0 +1,241 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#include "sensorsconfig.h" +#include "sensorsconfig.moc" +#include "sensorbase.h" + +#include <klocale.h> +#include <kiconloader.h> +#include <klistview.h> +#include <knuminput.h> +#include <kconfig.h> +#include <kdebug.h> +#include <kinputdialog.h> + +#include <qtimer.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qcheckbox.h> +#include <qcursor.h> +#include <qpopupmenu.h> +#include <qpushbutton.h> + +class SensorViewItem : public QCheckListItem +{ + public: + SensorViewItem(QListView *parent, const QString &text1, + const QString &text2, const QString &text3, + const QString &text4) + : QCheckListItem(parent, text1, CheckBox) + { + setText(1, text2); + setText(2, text3); + setText(3, text4); + } +}; + +SensorsConfig::SensorsConfig(KSim::PluginObject *parent, const char *name) + : KSim::PluginPage(parent, name) +{ + m_layout = new QGridLayout(this); + m_layout->setSpacing(6); + m_neverShown = true; + + m_sensorView = new KListView(this); + m_sensorView->addColumn(i18n("No.")); + m_sensorView->addColumn(i18n("Label")); + m_sensorView->addColumn(i18n("Sensors")); + m_sensorView->addColumn(i18n("Value")); + m_sensorView->setColumnWidth(0, 40); + m_sensorView->setColumnWidth(1, 60); + m_sensorView->setColumnWidth(2, 80); + m_sensorView->setAllColumnsShowFocus(true); + connect(m_sensorView, SIGNAL(contextMenu(KListView *, + QListViewItem *, const QPoint &)), this, SLOT(menu(KListView *, + QListViewItem *, const QPoint &))); + + connect( m_sensorView, SIGNAL( doubleClicked( QListViewItem * ) ), + SLOT( modify( QListViewItem * ) ) ); + + m_layout->addMultiCellWidget(m_sensorView, 1, 1, 0, 3); + + m_modify = new QPushButton( this ); + m_modify->setText( i18n( "Modify..." ) ); + connect( m_modify, SIGNAL( clicked() ), SLOT( modify() ) ); + m_layout->addMultiCellWidget( m_modify, 2, 2, 3, 3 ); + + m_fahrenBox = new QCheckBox(i18n("Display Fahrenheit"), this); + m_layout->addMultiCellWidget(m_fahrenBox, 3, 3, 0, 3); + + m_updateLabel = new QLabel(this); + m_updateLabel->setText(i18n("Update interval:")); + m_updateLabel->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, + QSizePolicy::Fixed)); + m_layout->addMultiCellWidget(m_updateLabel, 4, 4, 0, 0); + + m_sensorSlider = new KIntSpinBox(this); + m_layout->addMultiCellWidget(m_sensorSlider, 4, 4, 1, 1); + + QLabel *intervalLabel = new QLabel(this); + intervalLabel->setText(i18n("seconds")); + intervalLabel->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, + QSizePolicy::Fixed)); + m_layout->addMultiCellWidget(intervalLabel, 4, 4, 2, 2); +} + +SensorsConfig::~SensorsConfig() +{ +} + +void SensorsConfig::saveConfig() +{ + config()->setGroup("Sensors"); + config()->writeEntry("sensorUpdateValue", m_sensorSlider->value()); + config()->writeEntry("displayFahrenheit", m_fahrenBox->isChecked()); + + for (QListViewItemIterator it(m_sensorView); it.current(); ++it) { + config()->setGroup("Sensors"); + config()->writeEntry(it.current()->text(2), + QString::number(static_cast<QCheckListItem *>(it.current())->isOn()) + + ":" + it.current()->text(1)); + } +} + +void SensorsConfig::readConfig() +{ + config()->setGroup("Sensors"); + m_fahrenBox->setChecked(config()->readBoolEntry("displayFahrenheit", false)); + m_sensorSlider->setValue(config()->readNumEntry("sensorUpdateValue", 15)); + + QStringList names; + for (QListViewItemIterator it(m_sensorView); it.current(); ++it) { + config()->setGroup("Sensors"); + names = QStringList::split(":", config()->readEntry(it.current()->text(2), "0:")); + if (!names[1].isNull()) + it.current()->setText(1, names[1]); + static_cast<QCheckListItem *>(it.current())->setOn(names[0].toInt()); + } +} + +void SensorsConfig::menu(KListView *, QListViewItem *, const QPoint &) +{ + m_popupMenu = new QPopupMenu(this); + + m_popupMenu->insertItem(i18n("Select All"), 1); + m_popupMenu->insertItem(i18n("Unselect All"), 2); + m_popupMenu->insertItem(i18n("Invert Selection"), 3); + + switch (m_popupMenu->exec(QCursor::pos())) { + case 1: + selectAll(); + break; + case 2: + unSelectAll(); + break; + case 3: + invertSelect(); + break; + } + + delete m_popupMenu; +} + +void SensorsConfig::selectAll() +{ + for (QListViewItemIterator it(m_sensorView); it.current(); ++it) + static_cast<QCheckListItem *>(it.current())->setOn(true); +} + +void SensorsConfig::unSelectAll() +{ + for (QListViewItemIterator it(m_sensorView); it.current(); ++it) + static_cast<QCheckListItem *>(it.current())->setOn(false); +} + +void SensorsConfig::invertSelect() +{ + for (QListViewItemIterator it(m_sensorView); it.current(); ++it) { + QCheckListItem *item = static_cast<QCheckListItem *>(it.current()); + if (item->isOn()) + item->setOn(false); + else + item->setOn(true); + } +} + +void SensorsConfig::initSensors() +{ + const SensorList &sensorList = SensorBase::self()->sensorsList(); + + int i = 0; + QString label; + QStringList sensorInfo; + SensorList::ConstIterator it; + for (it = sensorList.begin(); it != sensorList.end(); ++it) { + label.sprintf("%02i", ++i); + (void) new SensorViewItem(m_sensorView, label, + (*it).sensorName(), (*it).sensorType() + "/" + (*it).sensorName(), + (*it).sensorValue() + (*it).sensorUnit()); + } + + QStringList names; + for (QListViewItemIterator it(m_sensorView); it.current(); ++it) { + config()->setGroup("Sensors"); + names = QStringList::split(":", config()->readEntry(it.current()->text(2), "0:")); + if (!names[1].isNull()) + it.current()->setText(1, names[1]); + static_cast<QCheckListItem *>(it.current())->setOn(names[0].toInt()); + } +} + +void SensorsConfig::modify( QListViewItem * item ) +{ + if ( !item ) + return; + + bool ok = false; + QString text = KInputDialog::getText( i18n( "Modify Sensor Label" ), i18n( "Sensor label:" ), + item->text( 1 ), &ok, this ); + + if ( ok ) + item->setText( 1, text ); +} + +void SensorsConfig::modify() +{ + modify( m_sensorView->selectedItem() ); +} + +void SensorsConfig::showEvent(QShowEvent *) +{ + if (m_neverShown) { + initSensors(); + m_neverShown = false; + } + else { + const SensorList &list = SensorBase::self()->sensorsList(); + SensorList::ConstIterator it; + for (it = list.begin(); it != list.end(); ++it) { + QListViewItem *item = m_sensorView->findItem((*it).sensorName(), 1); + if (item) + item->setText(3, (*it).sensorValue() + (*it).sensorUnit()); + } + } +} diff --git a/ksim/monitors/lm_sensors/sensorsconfig.h b/ksim/monitors/lm_sensors/sensorsconfig.h new file mode 100644 index 0000000..28d656e --- /dev/null +++ b/ksim/monitors/lm_sensors/sensorsconfig.h @@ -0,0 +1,69 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#ifndef SENSORSIMPL_H +#define SENSORSIMPL_H + +#include <pluginmodule.h> + +class QPushButton; +class QCheckListItem; +class QGridLayout; +class QLabel; +class KListView; +class QListViewItem; +class QPopupMenu; +class KIntSpinBox; +class QCheckBox; +class QTimer; + +class SensorsConfig : public KSim::PluginPage +{ + Q_OBJECT + public: + SensorsConfig(KSim::PluginObject *parent, const char *name); + ~SensorsConfig(); + + void saveConfig(); + void readConfig(); + + private slots: + void menu(KListView *, QListViewItem *, const QPoint &); + void initSensors(); + void selectAll(); + void unSelectAll(); + void invertSelect(); + + void modify( QListViewItem * ); + void modify(); + + protected: + void showEvent(QShowEvent *); + + private: + bool m_neverShown; + QLabel *m_updateLabel; + KIntSpinBox *m_sensorSlider; + KListView *m_sensorView; + QCheckBox *m_fahrenBox; + QGridLayout *m_layout; + QPopupMenu *m_popupMenu; + QPushButton * m_modify; +}; +#endif diff --git a/ksim/monitors/mail/Makefile.am b/ksim/monitors/mail/Makefile.am new file mode 100644 index 0000000..bf89a1d --- /dev/null +++ b/ksim/monitors/mail/Makefile.am @@ -0,0 +1,15 @@ +kde_module_LTLIBRARIES = ksim_mail.la +ksim_mail_la_SOURCES = ksimmail.cpp + +ksim_mail_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +ksim_mail_la_LIBADD = $(LIB_KIO) ../../library/libksimcore.la + +EXTRA_DIST = mail.desktop + +INCLUDES= -I$(top_srcdir)/ksim/library \ + $(all_includes) + +METASOURCES = AUTO + +mon_DATA = mail.desktop +mondir = $(kde_datadir)/ksim/monitors diff --git a/ksim/monitors/mail/ksimmail.cpp b/ksim/monitors/mail/ksimmail.cpp new file mode 100644 index 0000000..6ca1142 --- /dev/null +++ b/ksim/monitors/mail/ksimmail.cpp @@ -0,0 +1,160 @@ +/* + Copyright (c) 2002 Malte Starostik <malte@kde.org> + + 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; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +// $Id$ + +#include <qbitmap.h> +#include <qlayout.h> +#include <qtimer.h> + +#include <kaboutapplication.h> +#include <kdebug.h> +#include <klocale.h> + +#include <label.h> +#include <themeloader.h> +#include <themetypes.h> + +#include "ksimmail.moc" + +KSIM_INIT_PLUGIN( MailPlugin ); + +MailPlugin::MailPlugin( const char* name ) + : KSim::PluginObject( name ) +{ + setConfigFileName(instanceName()); +} + +MailPlugin::~MailPlugin() +{ +} + +KSim::PluginView* MailPlugin::createView( const char* name ) +{ + return new MailView( this, name ); +} + +KSim::PluginPage* MailPlugin::createConfigPage( const char* name ) +{ + return new MailConfig( this, name ); +} + +void MailPlugin::showAbout() +{ + KAboutData about( instanceName(), + I18N_NOOP( "KSim Mail Plugin" ), "0.1", + I18N_NOOP( "A mail monitor plugin for KSim" ), + KAboutData::License_GPL, "(c) 2002 Malte Starostik" ); + about.addAuthor( "Malte Starostik", I18N_NOOP( "Author" ), "malte@kde.org" ); + + KAboutApplication( &about ).exec(); +} + +MailView::MailView( KSim::PluginObject* parent, const char* name ) + : KSim::PluginView( parent, name ) +{ + QVBoxLayout* layout = new QVBoxLayout( this ); + + MailLabel* label = new MailLabel( this ); + layout->addWidget( label, 0, AlignHCenter ); +} + +MailView::~MailView() +{ +} + +void MailView::reparseConfig() +{ +} + +void MailView::updateDisplay() +{ +} + +MailLabel::MailLabel( QWidget* parent ) + : KSim::Label( KSim::Types::Mail, parent ) +{ +// label->setPixmap( KSim::ThemeLoader::self().current().krellMail() ); + configureObject( false ); + QTimer* timer = new QTimer( this ); + connect( timer, SIGNAL( timeout() ), SLOT( animation() ) ); + timer->start( 100 ); +} + +MailLabel::~MailLabel() +{ +} + +void MailLabel::configureObject( bool repaint ) +{ + m_envelope.load( themeLoader().current().mailPixmap() ); + m_frames = themeLoader().current().mailFrames(); + m_delay = themeLoader().current().mailDelay(); + + if ( !m_frames ) m_frames = 18; + if ( !m_delay ) m_delay = 1; + + setPixmap( frame( m_envelope, 1 ) ); + + KSim::Label::configureObject( repaint ); +} + +void MailLabel::paintEvent( QPaintEvent* e ) +{ + KSim::Label::paintEvent( e ); +} + +void MailLabel::animation() +{ + static int f = 1; + setPixmap( frame( m_envelope, f ) ); + if ( f++ >= m_frames ) f = 1; +} + +QPixmap MailLabel::frame( const QPixmap& source, int number ) const +{ + QPixmap result( source.width(), source.height() / m_frames ); + bitBlt( &result, 0, 0, &source, 0, number * source.height() / m_frames ); + if ( source.mask() ) + { + QBitmap mask( result.size() ); + bitBlt( &mask, 0, 0, source.mask(), 0, number * source.height() / m_frames ); + result.setMask( mask ); + } + return result; +} + +MailConfig::MailConfig( KSim::PluginObject* parent, const char* name ) + : KSim::PluginPage( parent, name ) +{ +} + +MailConfig::~MailConfig() +{ +} + +void MailConfig::saveConfig() +{ +} + +void MailConfig::readConfig() +{ +} + +// vim: ts=4 sw=4 noet diff --git a/ksim/monitors/mail/ksimmail.h b/ksim/monitors/mail/ksimmail.h new file mode 100644 index 0000000..fd8790a --- /dev/null +++ b/ksim/monitors/mail/ksimmail.h @@ -0,0 +1,90 @@ +/* + Copyright (c) 2002 Malte Starostik <malte@kde.org> + + 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; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +// $Id$ + +#ifndef __ksimmail_h__ +#define __ksimmail_h__ + +#include <pluginmodule.h> + +class MailPlugin : public KSim::PluginObject +{ +public: + MailPlugin( const char* name ); + ~MailPlugin(); + + virtual KSim::PluginView* createView( const char* ); + virtual KSim::PluginPage* createConfigPage( const char* ); + + virtual void showAbout(); +}; + +class MailView : public KSim::PluginView +{ + Q_OBJECT +public: + MailView( KSim::PluginObject* parent, const char* name ); + ~MailView(); + + virtual void reparseConfig(); + +private slots: + void updateDisplay(); +}; + +class MailLabel : public KSim::Label +{ + Q_OBJECT +public: + MailLabel( QWidget* parent ); + virtual ~MailLabel(); + + virtual void configureObject( bool ); + +protected: + virtual void paintEvent( QPaintEvent* ); + +private slots: + void animation(); + +private: + QPixmap frame( const QPixmap& source, int number ) const; + +private: + QPixmap m_envelope; + QPixmap m_penguin; + int m_frames; + int m_delay; +}; + +class MailConfig : public KSim::PluginPage +{ + Q_OBJECT +public: + MailConfig( KSim::PluginObject* parent, const char* name ); + ~MailConfig(); + + virtual void saveConfig(); + virtual void readConfig(); +}; + +#endif + +// vim: ts=4 sw=4 noet diff --git a/ksim/monitors/mail/mail.desktop b/ksim/monitors/mail/mail.desktop new file mode 100644 index 0000000..f65ed27 --- /dev/null +++ b/ksim/monitors/mail/mail.desktop @@ -0,0 +1,119 @@ +[Desktop Entry] +Comment=Mail Monitor Plugin +Comment[af]=Pos Monitor Inplak +Comment[ar]=ملØÙ‚ مراقبة البريد +Comment[bg]=Мониторинг на електронната поща +Comment[bs]=Dodatak za praćenje poÅ¡te +Comment[ca]=Monitor de correu +Comment[cs]=Modul pro monitorovánà poÅ¡ty +Comment[cy]=Atodyn Monitro Post +Comment[da]=PostovervÃ¥gnings-plugin +Comment[de]=Hilfsprogramm zur Mailüberwachung +Comment[el]=Î Ïόσθετο εποπτείας αλληλογÏαφίας +Comment[eo]=Disk-observa kromaĵo +Comment[es]=Extensión de monitorización de correo +Comment[et]=E-posti monitooring +Comment[eu]=Postaren Plugin Begiralea +Comment[fa]=وصلۀ نمایشگر نامه +Comment[fi]=Sähköpostin monitorointisovelma +Comment[fr]=Module de surveillance de boîtes aux lettres +Comment[ga]=Breiseán Monatóireachta RÃomhphoist +Comment[he]=תוסף צג דו×ר +Comment[hi]=डाक मॉनीटर पà¥à¤²à¤—इन +Comment[hu]=E-mail-figyelÅ‘ bÅ‘vÃtÅ‘modul +Comment[is]=Pósteftirlitsforrit +Comment[it]=Plugin di controllo posta +Comment[ja]=メールモニタプラグイン +Comment[ka]= ფáƒáƒ¡áƒ¢áƒ˜áƒ¡ მáƒáƒœáƒ˜áƒ¢áƒáƒ ის მáƒáƒ“ული +Comment[kk]=Поштаны бақылау модулі +Comment[km]=កម្មវិធី​ជំនួយ​របស់​កម្មវិធី​ážáŸ’ážšáž½ážáž–áž·áž“áž·ážáŸ’យ​សំបុážáŸ’ážš +Comment[lt]=PaÅ¡to stebÄ—tojo priedas +Comment[mk]=Приклучок за Ñледење на е-поштата +Comment[ms]=Plug masuk Pemerhati Mel +Comment[nb]=Programtillegg for E-postovervÃ¥king +Comment[nds]=Nettpost-Kiekmoduul +Comment[ne]=मेल मोनिटर पà¥à¤²à¤—इन +Comment[nl]=Mail monitor-plugin +Comment[nn]=Programtillegg for e-postovervaking +Comment[pa]=ਪੱਤਰ ਨਿਗਰਾਨ ਪਲੱਗਿੰਨ +Comment[pl]=Stan skrzynki pocztowej +Comment[pt]='Plugin' de Monitorização do Correio +Comment[pt_BR]=Plug-in de monitoramento de e-mail +Comment[ro]=Modul monitorizare e-mail +Comment[ru]=Монитор почты +Comment[sk]=Modul pre monitorovanie poÅ¡ty +Comment[sl]=Vstavek za opazovanje poÅ¡te +Comment[sr]=Прикључак за надгледање поште +Comment[sr@Latn]=PrikljuÄak za nadgledanje poÅ¡te +Comment[sv]=Insticksprogram för e-postövervakning +Comment[ta]= அஞà¯à®šà®²à¯ கணà¯à®•à®¾à®£à®¿ சொரà¯à®•à¯à®ªà¯à®ªà¯Šà®°à¯à®³à¯ +Comment[tg]=Модули Дидабони ПоÑÑ‚ +Comment[th]=ปลั๊à¸à¸à¸´à¸™à¸•à¸£à¸§à¸ˆà¸ªà¸à¸šà¸ˆà¸”หมาย +Comment[tr]=Posta Ä°zleyici Eklentisi +Comment[uk]=Втулок датчика пошти +Comment[uz]=Xat-xabarni nazorat qilish plagini +Comment[uz@cyrillic]=Хат-хабарни назорат қилиш плагини +Comment[wa]=Tchôke-divins di corwaitaedje di l' emilaedje +Comment[xh]=Iplagi efakiweyo Monitor Yeposi +Comment[zh_CN]=邮件监视器æ’件 +Comment[zh_TW]=é›»åéƒµä»¶ç›£è¦–å™¨å¤–æŽ›ç¨‹å¼ +Comment[zu]=I-plugin Yomlawuli Weposi +Icon=kmail +Name=Mail +Name[af]=Pos +Name[ar]=البريد +Name[bg]=Поща +Name[br]=Lizher +Name[ca]=Correu +Name[cs]=PoÅ¡ta +Name[cy]=Post +Name[da]=Post +Name[el]=ΑλληλογÏαφία +Name[eo]=RetpoÅto +Name[es]=Correo +Name[et]=Kirjad +Name[eu]=Posta +Name[fa]=نامه +Name[fi]=Sähköposti +Name[fr]=Courrier +Name[ga]=RÃomhphost +Name[he]=דו×ר +Name[hi]=डाक +Name[hr]=PoÅ¡ta +Name[is]=Póstur +Name[it]=Posta +Name[ja]=メール +Name[ka]=ფáƒáƒ¡áƒ¢áƒ +Name[kk]=Пошта +Name[km]=សំបុážáŸ’ážš +Name[lt]=PaÅ¡tas +Name[lv]=Pasts +Name[mk]=Е-пошта +Name[mt]=Imejl +Name[nb]=E-Post +Name[nds]=Nettpost +Name[ne]=मेल +Name[nn]=E-post +Name[pa]=ਪੱਤਰ +Name[pl]=Poczta +Name[pt]=E-mail +Name[pt_BR]=E-mail +Name[ru]=Почта +Name[sk]=PoÅ¡ta +Name[sl]=PoÅ¡ta +Name[sr]=Пошта +Name[sr@Latn]=PoÅ¡ta +Name[sv]=E-post +Name[ta]= அஞà¯à®šà®²à¯ +Name[tg]=ПоÑÑ‚ +Name[th]=จดหมาย +Name[tr]=E-posta +Name[uk]=Пошта +Name[uz]=Xat-xabar +Name[uz@cyrillic]=Хат-хабар +Name[wa]=Emilaedje +Name[xh]=Iposi +Name[zh_CN]=邮件 +Name[zh_TW]=é›»å郵件 +Name[zu]=Iposi +X-KSIM-LIBRARY=mail diff --git a/ksim/monitors/net/Makefile.am b/ksim/monitors/net/Makefile.am new file mode 100644 index 0000000..291eb71 --- /dev/null +++ b/ksim/monitors/net/Makefile.am @@ -0,0 +1,14 @@ +kde_module_LTLIBRARIES = ksim_net.la +ksim_net_la_SOURCES = ksimnet.cpp netdialog.cpp netconfig.cpp + +ksim_net_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +ksim_net_la_LIBADD = ../../library/libksimcore.la $(LIB_KIO) + +EXTRA_DIST = Net.desktop + +INCLUDES= -I$(top_srcdir)/ksim/library $(all_includes) + +METASOURCES = AUTO + +mon_DATA = Net.desktop +mondir = $(kde_datadir)/ksim/monitors diff --git a/ksim/monitors/net/Net.desktop b/ksim/monitors/net/Net.desktop new file mode 100644 index 0000000..2fa6b87 --- /dev/null +++ b/ksim/monitors/net/Net.desktop @@ -0,0 +1,112 @@ +[Desktop Entry] +Comment=Net Status Monitor +Comment[ar]=مراقب Øالة الشبكة +Comment[bg]=Мониторинг на мрежата +Comment[bs]=Nadzor statusa mreže +Comment[ca]=Monitor de l'estat de xarxa +Comment[cs]=Monitor stavu sÃtÄ› +Comment[cy]=Monitr Statws Rhwyd +Comment[da]=OvervÃ¥gning af netstatus +Comment[de]=Statusanzeige fürs Netzwerk +Comment[el]=Επόπτης κατάστασης δικτÏου +Comment[eo]=Rigardilo por la retstato +Comment[es]=Monitor de estado de la red +Comment[et]=Võrgu oleku monitooring +Comment[eu]=Sarearen Egoera Begiralea +Comment[fa]=Net نمایشگر وضعیت +Comment[fi]=Verkon tilavalvonta +Comment[fr]=Indicateur d'état réseau +Comment[ga]=Monatóir Stádais an Ghréasáin +Comment[he]=צג מצב רשת +Comment[hi]=नेट सà¥à¤¥à¤¿à¤¤à¤¿ मॉनीटर +Comment[hu]=Hálózati állapotfigyelÅ‘ +Comment[is]=Eftirlit með stöðu netsins +Comment[it]=Controllo dello stato della rete +Comment[ja]=ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯çŠ¶æ…‹ãƒ¢ãƒ‹ã‚¿ +Comment[ka]=ქსელის სტáƒáƒ¢áƒ£áƒ¡áƒ˜áƒ¡ სტáƒáƒ¢áƒ£áƒ¡áƒ˜ +Comment[kk]=Желінің күйін бақылау +Comment[km]=កម្មវិធី​ážáŸ’ážšáž½ážáž–áž·áž“áž·ážáŸ’យ​ស្ážáž¶áž“ភាព​បណ្ážáž¶áž‰ +Comment[lt]=Net bÅ«senos stebÄ—tojas +Comment[mk]=Монитор за ÑтатуÑот на мрежата +Comment[ms]=Pemerhati Status Net +Comment[nb]=OvervÃ¥kning av nettstatus +Comment[nds]=Statuskieker för't Nettwark +Comment[ne]=सञà¥à¤œà¤¾à¤² सà¥à¤¥à¤¿à¤¤à¤¿ मोनिटर +Comment[nl]=Netstatus-monitor +Comment[nn]=Overvaking av nettstatus +Comment[pa]=ਨੈੱਟ ਹਾਲਤ ਨਿਗਰਾਨ +Comment[pl]=Ruch w sieci +Comment[pt]=Monitor de Estado da Rede +Comment[pt_BR]=Monitor de estado da rede +Comment[ro]=Monitor stare reÅ£ea +Comment[ru]=Монитор Ñети +Comment[sk]=Monitor stavu siete +Comment[sl]=Nadzornik stanja mreže +Comment[sr]=Ðадгледање ÑтатуÑа мреже +Comment[sr@Latn]=Nadgledanje statusa mreže +Comment[sv]=Övervakar nätverkets status +Comment[ta]=வலை நிலை கணà¯à®•à®¾à®£à®¿ +Comment[tg]=Дидабони Ҳолати Шабака +Comment[th]=เครื่à¸à¸‡à¸¡à¸·à¸à¸ªà¸à¸”ส่à¸à¸‡à¸ªà¸–านะขà¸à¸‡à¹€à¸™à¹‡à¸• +Comment[tr]=AÄŸ İçin Durum Ä°zleyici +Comment[uk]=Монітор Ñтану мережі +Comment[uz]=Tarmoqni nazorat qilish plagini +Comment[uz@cyrillic]=Тармоқни назорат қилиш плагини +Comment[wa]=Corwaitoe di l' estat del rantoele +Comment[zh_CN]=网络状æ€ç›‘视器 +Comment[zh_TW]=網路狀態監視器 +Comment[zu]=Umlawuli Wezinga Lenethi +Icon=network +Name=Net +Name[ar]=الشبكة +Name[bg]=Мрежа +Name[br]=Rouedad +Name[ca]=Xarxa +Name[cs]=SÃÅ¥ +Name[cy]=Rhwyd +Name[el]=Δίκτυο +Name[eo]=Reto +Name[es]=Red +Name[ga]=Gréasán +Name[he]=רשת +Name[hi]=नेट +Name[is]=Netið +Name[it]=Rete +Name[ja]=ãƒãƒƒãƒˆ +Name[kk]=Желі +Name[km]=បណ្ážáž¶áž‰ +Name[lv]=TÄ«kls +Name[mk]=Мрежа +Name[nb]=Nett +Name[nds]=Nett +Name[ne]=सञà¥à¤œà¤¾à¤² +Name[nn]=Nett +Name[pa]=ਨੈੱਟ +Name[pl]=Sieć +Name[pt]=Rede +Name[pt_BR]=Rede +Name[ro]=ReÅ£ea +Name[ru]=Сеть +Name[sk]=SieÅ¥ +Name[sl]=Mreža +Name[sr]=Мрежа +Name[sr@Latn]=Mreža +Name[sv]=Nätverk +Name[ta]= வலை +Name[tg]=Шабака +Name[th]=เน็ต +Name[tr]=aÄŸ +Name[uk]=Мережа +Name[uz]=Tarmoq +Name[uz@cyrillic]=Тармоқ +Name[wa]=Rantoele +Name[xh]=Umnatha +Name[zh_CN]=网络 +Name[zh_TW]=網路 +Name[zu]=Inethi +X-KSIM-VERSION=0.1 +X-KSIM-LIBRARY=net +X-KSIM-COPYRIGHT=(C) 2001 Robbie Ward +X-KSIM-EMAIL=linuxphreak@gmx.co.uk +X-KSIM-PREFS=Network +X-KSIM-AUTHOR=Robbie Ward diff --git a/ksim/monitors/net/ksimnet.cpp b/ksim/monitors/net/ksimnet.cpp new file mode 100644 index 0000000..45f86c2 --- /dev/null +++ b/ksim/monitors/net/ksimnet.cpp @@ -0,0 +1,672 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#include <time.h> +#include <unistd.h> +#include <stdlib.h> +#include <sys/stat.h> + +#ifdef __FreeBSD__ +#include <sys/types.h> +#include <sys/sysctl.h> +#include <sys/socket.h> +#include <net/if.h> +#include <net/if_dl.h> +#include <net/route.h> + +static int mib[] = { CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0 }; +#endif + +#include <qpushbutton.h> +#include <qtextstream.h> +#include <qfile.h> +#include <qdatetime.h> +#include <qlayout.h> +#include <qtimer.h> +#include <qregexp.h> +#include <qcursor.h> +#include <qpopupmenu.h> + +#include <kdebug.h> +#include <klocale.h> +#include <kaboutapplication.h> +#include <kaboutdata.h> +#include <ksimpleconfig.h> +#include <kglobal.h> +#include <krun.h> +#include <kapplication.h> +#include <kiconloader.h> + +#include "ksimnet.h" +#include "netconfig.h" +#include <themetypes.h> + +#define NET_UPDATE 1000 +#define LED_UPDATE 125 + +KSIM_INIT_PLUGIN(NetPlugin) + +NetPlugin::NetPlugin(const char *name) + : KSim::PluginObject(name) +{ + setConfigFileName(instanceName()); +} + +NetPlugin::~NetPlugin() +{ +} + +KSim::PluginView *NetPlugin::createView(const char *className) +{ + return new NetView(this, className); +} + +KSim::PluginPage *NetPlugin::createConfigPage(const char *className) +{ + return new NetConfig(this, className); +} + +void NetPlugin::showAbout() +{ + QString version = kapp->aboutData()->version(); + + KAboutData aboutData(instanceName(), + I18N_NOOP("KSim Net Plugin"), version.latin1(), + I18N_NOOP("A net plugin for KSim"), + KAboutData::License_GPL, "(C) 2001 Robbie Ward"); + + aboutData.addAuthor("Robbie Ward", I18N_NOOP("Author"), + "linuxphreak@gmx.co.uk"); + aboutData.addAuthor("Heitham Omar", I18N_NOOP("FreeBSD ports"), + "super_ice@ntlworld.com"); + + KAboutApplication(&aboutData).exec(); +} + +NetView::NetView(KSim::PluginObject *parent, const char *name) + : KSim::PluginView(parent, name) +{ +#ifdef __linux__ + m_procStream = 0L; + if ((m_procFile = fopen("/proc/net/dev", "r"))) + m_procStream = new QTextStream(m_procFile, IO_ReadOnly); +#endif +#ifdef __FreeBSD__ + m_buf = 0; + m_allocSize = 0; +#endif + + m_firstTime = true; + m_netLayout = new QVBoxLayout(this); + + m_networkList = createList(); + addDisplay(); + + m_netTimer = new QTimer(this); + connect(m_netTimer, SIGNAL(timeout()), SLOT(updateGraph())); + m_netTimer->start(NET_UPDATE); + + m_lightTimer = new QTimer(this); + connect(m_lightTimer, SIGNAL(timeout()), SLOT(updateLights())); + m_lightTimer->start(LED_UPDATE); + + updateGraph(); +} + +NetView::~NetView() +{ +#ifdef __linux__ + delete m_procStream; + + if (m_procFile) + fclose(m_procFile); +#endif + + cleanup(); +} + +void NetView::reparseConfig() +{ + Network::List networkList = createList(); + if ( networkList == m_networkList ) + return; + + m_netTimer->stop(); + m_lightTimer->stop(); + m_firstTime = true; + + cleanup(); + + m_networkList = networkList; + addDisplay(); + + m_netTimer->start(NET_UPDATE); + m_lightTimer->start(LED_UPDATE); +} + +void NetView::cleanup() +{ + Network::List::Iterator it; + for ( it = m_networkList.begin(); it != m_networkList.end(); ++it ) + { + ( *it ).cleanup(); + } + + m_networkList.clear(); +} + +void NetView::addDisplay() +{ + int i = 0; + + Network::List::Iterator it; + for ( it = m_networkList.begin(); it != m_networkList.end(); ++it ) + { + KSim::LedLabel *led = addLedLabel( ( *it ).name() ); + KSim::Label *label = ( ( *it ).showTimer() ? addLabel() : 0L ); + QPopupMenu * popup = ( ( *it ).commandsEnabled() ? + addPopupMenu( ( *it ).name(), i ) : 0L ); + KSim::Chart *chart = addChart(); + //KSim::LedLabel *led = addLedLabel( ( *it ).name() ); + //KSim::Label *label = ( ( *it ).showTimer() ? addLabel() : 0L ); + //QPopupMenu * popup = ( ( *it ).commandsEnabled() ? + //addPopupMenu( ( *it ).name(), i ) : 0L ); + + if ( ( *it ).commandsEnabled() ) + { + if ( chart ) + { + chart->installEventFilter( this ); + } + + if ( led ) + { + led->installEventFilter( this ); + } + + if ( label ) + { + label->installEventFilter( this ); + } + } + + ( *it ).setDisplay( chart, led, label, popup ); + ++i; + } +} + +// Run the connect command +void NetView::runConnectCommand( int value ) +{ + int i = 0; + Network::List::ConstIterator it; + for ( it = m_networkList.begin(); it != m_networkList.end(); ++it ) + { + if ( value == i ) + { + // I use KRun here as it provides startup notification + if ( !( *it ).connectCommand().isNull() ) + { + KRun::runCommand( ( *it ).connectCommand() ); + } + + break; + } + ++i; + } +} + +// Run the disconnect command +void NetView::runDisconnectCommand( int value ) +{ + int i = 0; + Network::List::ConstIterator it; + for ( it = m_networkList.begin(); it != m_networkList.end(); ++it ) + { + if ( value == i ) + { + // I use KRun here as it provides startup notification + if ( !( *it ).disconnectCommand().isNull() ) + { + KRun::runCommand( ( *it ).disconnectCommand() ); + } + + break; + } + + ++i; + } +} + +Network::List NetView::createList() const +{ + config()->setGroup( "Net" ); + int amount = config()->readNumEntry( "deviceAmount", 0 ); + + Network::List list; + for ( int i = 0; i < amount; ++i ) + { + if ( !config()->hasGroup( "device-" + QString::number( i ) ) ) + { + continue; + } + + config()->setGroup( "device-" + QString::number( i ) ); + + list.append( Network( config()->readEntry( "deviceName" ), + config()->readEntry( "deviceFormat" ), + config()->readBoolEntry( "showTimer" ), + config()->readBoolEntry( "commands" ), + config()->readEntry( "cCommand" ), + config()->readEntry("dCommand") ) ); + } + + qHeapSort( list ); + return list; +} + +void NetView::updateLights() +{ + Network::List::Iterator it; + for ( it = m_networkList.begin(); it != m_networkList.end(); ++it ) + { + if ( isOnline( ( *it ).name() ) ) + { + unsigned long receiveDiff = ( *it ).data().in - ( *it ).oldData().in; + unsigned long sendDiff = ( *it ).data().out - ( *it ).oldData().out; + unsigned long halfMax = ( *it ).maxValue() / 2; + + ( *it ).led()->setMaxValue( ( *it ).maxValue() / 1024 ); + ( *it ).led()->setValue( receiveDiff / 1024 ); + + if ( receiveDiff == 0 ) + { + ( *it ).led()->setOff( KSim::Led::First ); + } + else if ( ( receiveDiff / 1024 ) >= halfMax ) + { + ( *it ).led()->setOn( KSim::Led::First ); + } + else + { + ( *it ).led()->toggle( KSim::Led::First ); + } + + if ( sendDiff == 0 ) + { + ( *it ).led()->setOff( KSim::Led::Second ); + } + else if ( ( sendDiff / 1024 ) >= halfMax ) + { + ( *it ).led()->setOn( KSim::Led::Second ); + } + else + { + ( *it ).led()->toggle( KSim::Led::Second ); + } + } + else + { + ( *it ).led()->setMaxValue( 0 ); + ( *it ).led()->setValue( 0 ); + ( *it ).led()->setOff( KSim::Led::First ); + ( *it ).led()->setOff( KSim::Led::Second ); + } + } +} + +void NetView::updateGraph() +{ + int timer = 0; + int hours = 0; + int minutes = 0; + int seconds = 0; + + time_t start = 0; + struct stat st; + + QTime netTime; + QString timeDisplay; + QString pid( "/var/run/%1.pid" ); + QString newPid; + + Network::List::Iterator it; + for ( it = m_networkList.begin(); it != m_networkList.end(); ++it ) + { + if ( isOnline( ( *it ).name() ) ) + { + NetData data; + + if ( ( *it ).label() ) + { + timeDisplay = ( *it ).format(); + newPid = pid.arg( ( *it ).name() ); + + if ( QFile::exists( newPid ) && stat( QFile::encodeName( newPid ).data(), &st ) == 0 ) + { + start = st.st_mtime; + + timer = static_cast<int>( difftime( time( 0 ), start ) ); + hours = timer / 3600; + minutes = (timer - hours * 3600) / 60; + seconds = timer % 60; + if ( netTime.isValid( hours, minutes, seconds ) ) + netTime.setHMS( hours, minutes, seconds ); + } + + // Keep backwards compat for now + if ( timeDisplay.contains( '%' ) > 0 ) + timeDisplay.replace( '%', "" ); + + ( *it ).label()->setText( netTime.toString( timeDisplay ) ); + } + + netStatistics( ( *it ).name(), data ); + ( *it ).setData( data ); + + unsigned long receiveDiff = data.in - ( *it ).oldData().in; + unsigned long sendDiff = data.out - ( *it ).oldData().out; + + if ( m_firstTime ) + { + receiveDiff = sendDiff = 0; + } + + ( *it ).chart()->setValue( receiveDiff, sendDiff ); + ( *it ).setMaxValue( ( *it ).chart()->maxValue() ); + + QString receiveString = KGlobal::locale()->formatNumber( ( float ) receiveDiff / 1024.0, 1 ); + QString sendString = KGlobal::locale()->formatNumber( ( float ) sendDiff / 1024.0, 1 ); + + ( *it ).chart()->setText( i18n( "in: %1k" ).arg( receiveString ), + i18n( "out: %1k" ).arg( sendString ) ); + } + else + { + ( *it ).setData( NetData() ); + ( *it ).chart()->setValue( 0, 0 ); + + ( *it ).chart()->setText( i18n( "in: %1k" ).arg( KGlobal::locale()->formatNumber( 0.0, 1 ) ), + i18n( "out: %1k" ).arg( KGlobal::locale()->formatNumber( 0.0, 1 ) ) ); + + if ( ( *it ).label() ) + ( *it ).label()->setText( i18n( "offline" ) ); + } + } + + if ( m_firstTime ) + m_firstTime = false; +} + +KSim::Chart *NetView::addChart() +{ + KSim::Chart *chart = new KSim::Chart(false, 0, this); + m_netLayout->addWidget(chart); + chart->show(); + return chart; +} + +KSim::LedLabel *NetView::addLedLabel(const QString &device) +{ + KSim::LedLabel *ledLabel = new KSim::LedLabel(0, KSim::Types::Net, + device, this); + + ledLabel->show(); + m_netLayout->addWidget(ledLabel); + return ledLabel; +} + +KSim::Label *NetView::addLabel() +{ + KSim::Label *label = new KSim::Label(KSim::Types::None, this); + label->show(); + m_netLayout->addWidget(label); + return label; +} + +QPopupMenu *NetView::addPopupMenu(const QString &device, int value) +{ + QPopupMenu *popup = new QPopupMenu(this); + popup->insertItem(SmallIcon("network"), i18n("Connect"), this, + SLOT(runConnectCommand(int)), 0, 1); + popup->setItemParameter(1, value); + popup->insertItem(SmallIcon("network"), i18n("Disconnect"), this, + SLOT(runDisconnectCommand(int)), 0, 2); + popup->setItemParameter(2, value); + menu()->insertItem(device, popup, 100 + value); + return popup; +} + +void NetView::netStatistics(const QString &device, NetData &data) +{ +#ifdef __linux__ + if (m_procFile == 0) { + data.in = 0; + data.out = 0; + return; + } + + QString output; + QString parser; + // Parse the proc file + while (!m_procStream->atEnd()) { + parser = m_procStream->readLine(); + // remove all the entries apart from the line containing 'device' + if (parser.find(device) != -1) + output = parser; + } + + if (output.isEmpty()) { + data.in = 0; + data.out = 0; + return; + } + + // make sure our output doesn't contain "eth0:11210107" so we dont + // end up with netList[1] actually being netList[2] + output.replace(QRegExp(":"), " "); + QStringList netList = QStringList::split(' ', output); + + data.in = netList[1].toULong(); + data.out = netList[9].toULong(); + + fseek(m_procFile, 0L, SEEK_SET); +#endif + +#ifdef __FreeBSD__ + struct if_msghdr *ifm, *nextifm; + struct sockaddr_dl *sdl; + char *lim, *next; + size_t needed; + char s[32]; + + if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) + return; + + if (m_allocSize < needed) { + if (m_buf != NULL) + delete[] m_buf; + + m_buf = new char[needed]; + + if (m_buf == NULL) + return; + + m_allocSize = needed; + } + + if (sysctl(mib, 6, m_buf, &needed, NULL, 0) < 0) + return; + + lim = m_buf + needed; + + next = m_buf; + while (next < lim) { + ifm = (struct if_msghdr *)next; + if (ifm->ifm_type != RTM_IFINFO) + return; + + next += ifm->ifm_msglen; + + // get an interface with a network address + while (next < lim) { + nextifm = (struct if_msghdr *)next; + if (nextifm->ifm_type != RTM_NEWADDR) + break; + + next += nextifm->ifm_msglen; + } + + // if the interface is up + if (ifm->ifm_flags & IFF_UP) { + sdl = (struct sockaddr_dl *)(ifm + 1); + if (sdl->sdl_family != AF_LINK) + continue; + + strncpy(s, sdl->sdl_data, sdl->sdl_nlen); + s[sdl->sdl_nlen] = '\0'; + + if (strcmp(device.local8Bit().data(), s) == 0) { + data.in = ifm->ifm_data.ifi_ibytes; + data.out = ifm->ifm_data.ifi_obytes; + return; + } + } + } +#endif +} + +bool NetView::isOnline(const QString &device) +{ +#ifdef __linux__ + QFile file("/proc/net/route"); + if (!file.open(IO_ReadOnly)) + return -1; + + return (QTextStream(&file).read().find(device) != -1 ? true : false); +#endif + +#ifdef __FreeBSD__ + struct if_msghdr *ifm, *nextifm; + struct sockaddr_dl *sdl; + char *lim, *next; + size_t needed; + char s[32]; + + if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) + return false; + + if (m_allocSize < needed) { + if (m_buf != NULL) + delete[] m_buf; + + m_buf = new char[needed]; + + if (m_buf == NULL) + return false; + + m_allocSize = needed; + } + + if (sysctl(mib, 6, m_buf, &needed, NULL, 0) < 0) + return false; + + lim = m_buf + needed; + + next = m_buf; + while (next < lim) { + ifm = (struct if_msghdr *)next; + if (ifm->ifm_type != RTM_IFINFO) + return false; + + next += ifm->ifm_msglen; + + // get an interface with a network address + while (next < lim) { + nextifm = (struct if_msghdr *)next; + if (nextifm->ifm_type != RTM_NEWADDR) + break; + + next += nextifm->ifm_msglen; + } + + // if the interface is up + if (ifm->ifm_flags & IFF_UP) { + sdl = (struct sockaddr_dl *)(ifm + 1); + if (sdl->sdl_family != AF_LINK) + continue; + + strncpy(s, sdl->sdl_data, sdl->sdl_nlen); + s[sdl->sdl_nlen] = '\0'; + + if (strcmp(s, device.local8Bit().data()) == 0) + return true; + } + } + + return false; +#endif +} + +// EventFilter +bool NetView::eventFilter( QObject * o, QEvent * e ) +{ + // find out which interface we are + int i = 0; + Network::List::Iterator it; + for ( it = m_networkList.begin(); it != m_networkList.end(); ++it ) + { + if ( o == ( *it ).chart() || o == ( *it ).label() || o == ( *it ).led() ) + { + break; + } + + ++i; + } + + if ( e->type() == QEvent::MouseButtonPress ) + { + if ( static_cast<QMouseEvent *>( e )->button() == QMouseEvent::RightButton ) + { + showMenu(i); + } + + return true; + } + + return false; +} + +void NetView::showMenu(int i) { + + QPopupMenu menu; + menu.insertItem( SmallIcon("network"), i18n("Connect"), 1); + menu.insertItem( SmallIcon("network"), i18n("Disconnect"), 2); + switch (menu.exec(QCursor::pos())) { + case 1: + runConnectCommand(i); + break; + case 2: + runDisconnectCommand(i); + break; + } +} + + +#include "ksimnet.moc" diff --git a/ksim/monitors/net/ksimnet.h b/ksim/monitors/net/ksimnet.h new file mode 100644 index 0000000..bdb76e6 --- /dev/null +++ b/ksim/monitors/net/ksimnet.h @@ -0,0 +1,90 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#ifndef KSIMNET_H +#define KSIMNET_H + +#include <pluginmodule.h> +#include "netdevices.h" +#include <stdio.h> + +class QTimer; +class QVBoxLayout; +class QTextStream; + +class NetPlugin : public KSim::PluginObject +{ + public: + NetPlugin(const char *name); + ~NetPlugin(); + + virtual KSim::PluginView *createView(const char *); + virtual KSim::PluginPage *createConfigPage(const char *); + + virtual void showAbout(); +}; + +class NetView : public KSim::PluginView +{ + Q_OBJECT + public: + NetView(KSim::PluginObject *parent, const char *name); + ~NetView(); + + virtual void reparseConfig(); + + private slots: + void cleanup(); + void updateLights(); + void updateGraph(); + void addDisplay(); + void runConnectCommand(int); + void runDisconnectCommand(int); + + protected: + bool eventFilter(QObject *, QEvent *); + + private: + Network::List createList() const; + + KSim::Chart *addChart(); + KSim::LedLabel *addLedLabel(const QString &device); + KSim::Label *addLabel(); + QPopupMenu *addPopupMenu(const QString &device, int value); + + void netStatistics(const QString &device, NetData &data); + bool isOnline(const QString &device); + + void showMenu(int i); + + bool m_firstTime; + Network::List m_networkList; + QTimer *m_netTimer; + QTimer *m_lightTimer; + QVBoxLayout *m_netLayout; +#ifdef __linux__ + FILE *m_procFile; + QTextStream *m_procStream; +#endif +#ifdef __FreeBSD__ + char *m_buf; + int m_allocSize; +#endif +}; +#endif diff --git a/ksim/monitors/net/netconfig.cpp b/ksim/monitors/net/netconfig.cpp new file mode 100644 index 0000000..ca424b3 --- /dev/null +++ b/ksim/monitors/net/netconfig.cpp @@ -0,0 +1,296 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#include <qpushbutton.h> +#include <qlayout.h> +#include <qcursor.h> + +#include <klistview.h> +#include <ksimpleconfig.h> +#include <klocale.h> +#include <kiconloader.h> +#include <kapplication.h> +#include <kpopupmenu.h> +#include <kdebug.h> +#include <kmessagebox.h> + +#include "netconfig.h" +#include "netconfig.moc" +#include "netdialog.h" + +NetConfig::NetConfig(KSim::PluginObject *parent, const char *name) + : KSim::PluginPage(parent, name) +{ + m_yes = i18n("yes"); + m_no = i18n("no"); + + QVBoxLayout *mainLayout = new QVBoxLayout(this); + mainLayout->setSpacing(6); + + usingBox = new KListView(this); + usingBox ->addColumn(i18n("Interface")); + usingBox ->addColumn(i18n("Timer")); + usingBox ->addColumn(i18n("Commands")); + usingBox->setAllColumnsShowFocus(true); + + connect(usingBox, SIGNAL(contextMenu(KListView *, + QListViewItem *, const QPoint &)), + SLOT(menu(KListView *, QListViewItem *, const QPoint &))); + connect(usingBox, SIGNAL(doubleClicked(QListViewItem *)), + SLOT(modifyItem(QListViewItem *))); + mainLayout->addWidget(usingBox); + + layout = new QHBoxLayout; + layout->setSpacing(6); + + QSpacerItem *spacer = new QSpacerItem(20, 20, + QSizePolicy::Expanding, QSizePolicy::Minimum); + layout->addItem(spacer); + + insertButton = new QPushButton(this); + insertButton->setText(i18n("Add...")); + connect(insertButton, SIGNAL(clicked()), SLOT(showNetDialog())); + layout->addWidget(insertButton); + + modifyButton = new QPushButton(this); + modifyButton->setText(i18n("Modify...")); + connect(modifyButton, SIGNAL(clicked()), SLOT(modifyCurrent())); + layout->addWidget(modifyButton); + + removeButton = new QPushButton(this); + removeButton->setText(i18n("Remove")); + connect(removeButton, SIGNAL(clicked()), SLOT(removeCurrent())); + layout->addWidget(removeButton); + + mainLayout->addLayout(layout); +} + +NetConfig::~NetConfig() +{ +} + +void NetConfig::saveConfig() +{ + qHeapSort( m_networkList); + + int i = 0; + Network::List::Iterator it; + for( it = m_networkList.begin(); it != m_networkList.end(); ++it ) + { + config()->setGroup( "device-" + QString::number( i ) ); + config()->writeEntry( "deviceName", ( *it ).name() ); + config()->writeEntry( "showTimer", ( *it ).showTimer() ); + config()->writeEntry( "deviceFormat", ( *it ).format() ); + config()->writeEntry( "commands", ( *it ).commandsEnabled() ); + config()->writeEntry( "cCommand", ( *it ).connectCommand() ); + config()->writeEntry( "dCommand", ( *it ).disconnectCommand() ); + i++; + } + + config()->setGroup( "Net" ); + config()->writeEntry( "deviceAmount", m_networkList.count() ); +} + +void NetConfig::readConfig() +{ + usingBox->clear(); + m_networkList.clear(); + + config()->setGroup( "Net" ); + int deviceAmount = config()->readNumEntry( "deviceAmount" ); + + for ( int i = 0; i < deviceAmount; ++i ) + { + if ( !config()->hasGroup( "device-" + QString::number( i ) ) ) + { + continue; + } + + config()->setGroup("device-" + QString::number(i)); + + m_networkList.append( Network( config()->readEntry( "deviceName" ), + config()->readEntry( "deviceFormat" ), + config()->readBoolEntry( "showTimer" ), + config()->readBoolEntry( "commands" ), + config()->readEntry( "cCommand" ), + config()->readEntry( "dCommand" ) ) ); + + (void) new QListViewItem( usingBox, + config()->readEntry( "deviceName" ), + boolToString( config()->readBoolEntry( "showTimer" ) ), + boolToString( config()->readBoolEntry( "commands" ) ) ); + } +} + +void NetConfig::menu(KListView *, QListViewItem *item, const QPoint &) +{ + aboutMenu = new QPopupMenu(this); + + if (item) { + aboutMenu->insertItem(i18n("&Add Net Device"), 3); + aboutMenu->insertItem(i18n("&Modify '%1'").arg(item->text(0)), 2); + aboutMenu->insertItem(i18n("&Remove '%1'").arg(item->text(0)), 1); + } + else { + aboutMenu->insertItem(i18n("&Add Net Device"), 3); + aboutMenu->insertItem(i18n("&Modify..."), 2); + aboutMenu->insertItem(i18n("&Remove..."), 1); + aboutMenu->setItemEnabled(1, false); + aboutMenu->setItemEnabled(2, false); + } + + switch (aboutMenu->exec(QCursor::pos())) { + case 1: + removeItem(item); + break; + case 2: + modifyItem(item); + break; + case 3: + showNetDialog(); + break; + } + + delete aboutMenu; +} + +void NetConfig::modifyItem(QListViewItem *item) +{ + if (!item) + return; + + netDialog = new NetDialog(this); + Network::List::Iterator it, netDevice; + for ( it = m_networkList.begin(); it != m_networkList.end(); ++it ) + { + if ( ( *it ).name() == item->text( 0 ) ) + { + netDevice = it; + netDialog->setDeviceName( ( *it ).name() ); + netDialog->setShowTimer( ( *it ).showTimer() ); + netDialog->setFormat( ( *it ).format() ); + netDialog->setShowCommands( ( *it ).commandsEnabled() ); + netDialog->setCCommand( ( *it ).connectCommand() ); + netDialog->setDCommand( ( *it ).disconnectCommand() ); + break; + } + } + + netDialog->exec(); + if ( netDialog->okClicked() ) + { + m_networkList.remove( netDevice ); + m_networkList.append( Network( netDialog->deviceName(), + netDialog->format(), + netDialog->timer(), + netDialog->commands(), + netDialog->cCommand(), + netDialog->dCommand() ) ); + + item->setText( 0, netDialog->deviceName() ); + item->setText( 1, boolToString( netDialog->timer() ) ); + item->setText( 2, boolToString( netDialog->commands() ) ); + } + + delete netDialog; +} + +void NetConfig::removeItem(QListViewItem *item) +{ + if (!item) + return; + + int result = KMessageBox::warningContinueCancel(0, i18n("Are you sure you " + "want to remove the net interface '%1'?").arg(item->text(0)), QString::null, KStdGuiItem::del()); + + if (result == KMessageBox::Cancel) + return; + + int i = 0; + Network::List::Iterator it; + for ( it = m_networkList.begin(); it != m_networkList.end(); ++it ) + { + if ( item->text( 0 ) == ( *it ).name() ) + { + m_networkList.remove( it ); + if ( config()->deleteGroup( "device-" + QString::number( i ) ) ) + kdDebug(2003) << "device-" << i << " was deleted" << endl; + + break; + } + i++; + } + + delete item; +} + +void NetConfig::removeCurrent() +{ + removeItem(usingBox->currentItem()); +} + +void NetConfig::modifyCurrent() +{ + modifyItem(usingBox->currentItem()); +} + +void NetConfig::showNetDialog() +{ + netDialog = new NetDialog(this, "netDialog"); + netDialog->exec(); + if (netDialog->okClicked()) + getStats(); + + delete netDialog; +} + +void NetConfig::getStats() +{ + Network::List::ConstIterator it; + for ( it = m_networkList.begin(); it != m_networkList.end(); ++it ) + { + if ( ( *it ).name() == netDialog->deviceName() ) + { + KMessageBox::sorry(0, i18n("You already have a network " + "interface by this name. Please select a different interface")); + + return; + } + } + + m_networkList.append( Network( netDialog->deviceName(), + netDialog->format(), + netDialog->timer(), + netDialog->commands(), + netDialog->cCommand(), + netDialog->dCommand() ) ); + + (void) new QListViewItem( usingBox, + netDialog->deviceName(), + boolToString( netDialog->timer() ), + boolToString( netDialog->commands() ) ); +} + +const QString &NetConfig::boolToString(bool value) const +{ + if (value) + return m_yes; + + return m_no; +} diff --git a/ksim/monitors/net/netconfig.h b/ksim/monitors/net/netconfig.h new file mode 100644 index 0000000..9ec5c8d --- /dev/null +++ b/ksim/monitors/net/netconfig.h @@ -0,0 +1,67 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#ifndef NETCONFIG_H +#define NETCONFIG_H + +#include <pluginmodule.h> +#include "netdevices.h" + +class NetDialog; +class QPopupMenu; +class QPushButton; +class KListView; +class QHBoxLayout; +class QListViewItem; + +class NetConfig : public KSim::PluginPage +{ + Q_OBJECT + public: + NetConfig(KSim::PluginObject *parent, const char *name); + virtual ~NetConfig(); + + virtual void saveConfig(); + virtual void readConfig(); + + private slots: + void menu(KListView *, QListViewItem *, const QPoint &); + void modifyItem(QListViewItem *); + void removeItem(QListViewItem *); + void removeCurrent(); + void modifyCurrent(); + void showNetDialog(); + void getStats(); + + private: + // Couldnt think of a better name for this :) + const QString &boolToString(bool) const; + + QHBoxLayout *layout; + QPushButton *insertButton; + QPushButton *removeButton; + QPushButton *modifyButton; + KListView *usingBox; + NetDialog *netDialog; + Network::List m_networkList; + QString m_yes; + QString m_no; + QPopupMenu *aboutMenu; +}; +#endif diff --git a/ksim/monitors/net/netdevices.h b/ksim/monitors/net/netdevices.h new file mode 100644 index 0000000..2a5a680 --- /dev/null +++ b/ksim/monitors/net/netdevices.h @@ -0,0 +1,218 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#ifndef NETDEVICES_H +#define NETDEVICES_H + +#include <chart.h> +#include <led.h> + +class NetData +{ + public: + NetData() : in(0), out(0) {} + NetData &operator=( const NetData & rhs ) + { + in = rhs.in; + out = rhs.out; + + return *this; + } + + unsigned long in; + unsigned long out; +}; + +class Network +{ + public: + typedef QValueList<Network> List; + + Network() + { + m_chart = 0; + m_led = 0; + m_label = 0; + m_popup = 0; + + m_max = 0; + } + + Network( const QString & name, + const QString & format, + bool timer, + bool commands, + const QString & cCommand, + const QString & dCommand ) + : m_name( name ), + m_format( format ), + m_timer( timer ), + m_commands( commands ), + m_cCommand( cCommand ), + m_dCommand( dCommand ) + { + m_chart = 0; + m_led = 0; + m_label = 0; + m_popup = 0; + + m_max = 0; + } + + bool operator==( const Network & rhs ) const + { + return m_name == rhs.m_name && + m_format == rhs.m_format && + m_timer == rhs.m_timer && + m_commands == rhs.m_commands && + m_cCommand == rhs.m_cCommand && + m_dCommand == rhs.m_dCommand; + } + + bool operator!=( const Network & rhs ) const + { + return !operator==(rhs); + } + + bool operator<( const Network & rhs ) const + { + return m_name < rhs.m_name; + } + + bool operator>( const Network & rhs ) const + { + return m_name > rhs.m_name; + } + + bool operator<=( const Network & rhs ) const + { + return !( *this > rhs ); + } + + void cleanup() + { + delete m_chart; + delete m_label; + delete m_led; + delete m_popup; + + m_chart = 0; + m_label = 0; + m_led = 0; + m_popup = 0; + } + + void setData( const NetData & data ) + { + m_old = m_data; + m_data = data; + } + + const NetData & data() const + { + return m_data; + } + + const NetData & oldData() const + { + return m_old; + } + + void setMaxValue( int max ) + { + m_max = max; + } + + int maxValue() const + { + return m_max; + } + + const QString & name() const + { + return m_name; + } + + bool showTimer() const + { + return m_timer; + } + + const QString & format() const + { + return m_format; + } + + bool commandsEnabled() const + { + return m_commands; + } + + const QString & connectCommand() const + { + return m_cCommand; + } + + const QString & disconnectCommand() const + { + return m_dCommand; + } + + void setDisplay( KSim::Chart * chart, KSim::LedLabel * led, + KSim::Label * label, QPopupMenu * popup ) + { + m_chart = chart; + m_led = led; + m_label = label; + m_popup = popup; + } + + KSim::Chart * chart() + { + return m_chart; + } + + KSim::LedLabel * led() + { + return m_led; + } + + KSim::Label * label() + { + return m_label; + } + + private: + NetData m_data; + NetData m_old; + QString m_name; + QString m_format; + bool m_timer; + bool m_commands; + QString m_cCommand; + QString m_dCommand; + + KSim::Chart * m_chart; + KSim::LedLabel * m_led; + KSim::Label * m_label; + QPopupMenu * m_popup; + + int m_max; +}; +#endif diff --git a/ksim/monitors/net/netdialog.cpp b/ksim/monitors/net/netdialog.cpp new file mode 100644 index 0000000..fe655d4 --- /dev/null +++ b/ksim/monitors/net/netdialog.cpp @@ -0,0 +1,328 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#include "netdialog.h" +#include "netdialog.moc" + +#include <qcheckbox.h> +#include <qgroupbox.h> +#include <qlabel.h> +#include <qpushbutton.h> +#include <qtabwidget.h> +#include <qwidget.h> +#include <qlayout.h> +#include <qfile.h> +#include <qregexp.h> + +#include <klocale.h> +#include <kcombobox.h> +#include <kdebug.h> +#include <klineedit.h> +#include <kapplication.h> +#include <kurlrequester.h> +#include <kstdguiitem.h> + +#ifdef __FreeBSD__ +#include <sys/types.h> +#include <sys/sysctl.h> +#include <sys/socket.h> +#include <net/if.h> +#include <net/if_dl.h> +#include <net/route.h> +#endif + +#include <string.h> + +NetDialog::NetDialog(QWidget *parent, const char *name) + : QTabDialog(parent, name, true) +{ + m_clicked = false; + setCaption(kapp->makeStdCaption(i18n("Network Interface"))); + + m_generalTab = new QWidget(this); + m_generalLayout = new QGridLayout(m_generalTab); + m_generalLayout->setSpacing(6); + m_generalLayout->setMargin(11); + + m_deviceLabel = new QLabel(m_generalTab); + m_deviceLabel->setText(i18n("Interface:")); + m_generalLayout->addMultiCellWidget(m_deviceLabel, 0, 0, 0, 0); + + m_deviceCombo = new KComboBox(true, m_generalTab); + m_deviceCombo->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, + QSizePolicy::Fixed)); + m_deviceCombo->setFocus(); + m_deviceCombo->setDuplicatesEnabled(false); + m_generalLayout->addMultiCellWidget(m_deviceCombo, 0, 0, 1, 1); + + QStringList output(createList()); + if (output.isEmpty()) { + m_deviceCombo->insertItem("ppp0"); + m_deviceCombo->insertItem("eth0"); + } + else + m_deviceCombo->insertStringList(output); + + QSpacerItem *deviceSpacer = new QSpacerItem(20, 20, + QSizePolicy::Expanding, QSizePolicy::Fixed); + m_generalLayout->addMultiCell(deviceSpacer, 0, 0, 2, 2); + + m_timerBox = new QGroupBox(m_generalTab); + m_timerBox->setTitle(i18n("Timer")); + m_timerBox->setColumnLayout(0, Qt::Vertical); + m_timerBox->layout()->setSpacing(0); + m_timerBox->layout()->setMargin(0); + m_timerBoxLayout = new QVBoxLayout(m_timerBox->layout()); + m_timerBoxLayout->setAlignment(Qt::AlignTop); + m_timerBoxLayout->setSpacing(6); + m_timerBoxLayout->setMargin(11); + + m_timerEdit = new KLineEdit(m_timerBox); + m_timerEdit->setText("hh:mm:ss"); + m_timerEdit->setEnabled(false); + + m_showTimer = new QCheckBox(m_timerBox); + m_showTimer->setText(i18n("Show timer")); + connect(m_showTimer, SIGNAL(toggled(bool)), + m_timerEdit, SLOT(setEnabled(bool))); + m_timerBoxLayout->addWidget(m_showTimer); + m_timerBoxLayout->addWidget(m_timerEdit); + + m_hFormat = new QLabel(m_timerBox); + m_hFormat->setText(i18n("hh - Total hours online")); + m_timerBoxLayout->addWidget(m_hFormat); + + m_mFormat = new QLabel(m_timerBox); + m_mFormat->setText(i18n("mm - Total minutes online")); + m_timerBoxLayout->addWidget(m_mFormat); + + m_sFormat = new QLabel(m_timerBox); + m_sFormat->setText(i18n("ss - Total seconds online")); + m_timerBoxLayout->addWidget(m_sFormat); + m_generalLayout->addMultiCellWidget(m_timerBox, 1, 1, 0, 2); + + QSpacerItem *spacer = new QSpacerItem(20, 20, + QSizePolicy::Minimum, QSizePolicy::Expanding); + m_generalLayout->addMultiCell(spacer, 2, 2, 0, 0); + addTab(m_generalTab, i18n("General")); + + m_commandTab = new QWidget(this); + m_commandLayout = new QGridLayout(m_commandTab); + m_commandLayout->setSpacing(6); + m_commandLayout->setMargin(11); + + m_enableCommands = new QCheckBox(m_commandTab); + m_enableCommands->setText(i18n("Enable connect/disconnect")); + m_commandLayout->addMultiCellWidget(m_enableCommands, 0, 0, 0, 2); + + m_cCommand = new QLabel(m_commandTab); + m_cCommand->setText(i18n("Connect command:")); + m_commandLayout->addMultiCellWidget(m_cCommand, 1, 1, 0, 0); + + m_connectRequester = new KURLRequester(m_commandTab); + m_connectRequester->setMinimumSize(145, 0); + m_connectRequester->setEnabled(false); + connect(m_enableCommands, SIGNAL(toggled(bool)), + m_connectRequester, SLOT(setEnabled(bool))); + m_commandLayout->addMultiCellWidget(m_connectRequester, 1, 1, 1, 2); + + m_dCommand = new QLabel(m_commandTab); + m_dCommand->setText(i18n("Disconnect command:")); + m_commandLayout->addMultiCellWidget(m_dCommand, 2, 2, 0, 0); + + m_disconnectRequester = new KURLRequester(m_commandTab); + m_disconnectRequester->setMinimumSize(145, 0); + m_disconnectRequester->setEnabled(false); + connect(m_enableCommands, SIGNAL(toggled(bool)), + m_disconnectRequester, SLOT(setEnabled(bool))); + m_commandLayout->addMultiCellWidget(m_disconnectRequester, 2, 2, 1, 2); + + QSpacerItem *commandSpacer = new QSpacerItem(20, 20, + QSizePolicy::Minimum, QSizePolicy::Expanding); + m_commandLayout->addItem(commandSpacer); + addTab(m_commandTab, i18n("Commands")); + + setOkButton(KStdGuiItem::ok().text()); + setCancelButton(KStdGuiItem::cancel().text()); + connect(this, SIGNAL(applyButtonPressed()), SLOT(sendClicked())); +} + +NetDialog::~NetDialog() +{ +} + +const QString NetDialog::deviceName() const +{ + return m_deviceCombo->currentText(); +} + +bool NetDialog::timer() +{ + return m_showTimer->isChecked(); +} + +const QString NetDialog::format() const +{ + return m_timerEdit->text(); +} + +bool NetDialog::commands() +{ + return m_enableCommands->isChecked(); +} + +const QString NetDialog::cCommand() const +{ + return m_connectRequester->url(); +} + +const QString NetDialog::dCommand() const +{ + return m_disconnectRequester->url(); +} + +void NetDialog::setDeviceName(const QString &text) +{ + m_deviceCombo->setCurrentItem(text, true); +} + +void NetDialog::setShowTimer(bool value) +{ + m_showTimer->setChecked(value); +} + +void NetDialog::setFormat(const QString &format) +{ + m_timerEdit->setText(format); +} + +void NetDialog::setShowCommands(bool value) +{ + m_enableCommands->setChecked(value); +} + +void NetDialog::setCCommand(const QString &text) +{ + m_connectRequester->setURL(text); +} + +void NetDialog::setDCommand(const QString &text) +{ + m_disconnectRequester->setURL(text); +} + +void NetDialog::sendClicked() +{ + m_clicked = true; + kdDebug(2003) << "ok was clicked" << endl; +} + +QStringList NetDialog::createList() const +{ +#ifdef __linux__ + QFile file("/proc/net/dev"); + if (!file.open(IO_ReadOnly)) + return QStringList(); + + QStringList output; + QTextStream textStream(&file); + while (!textStream.atEnd()) + output.append(textStream.readLine()); + + if (output.isEmpty()) + return QStringList(); + + output.pop_front(); + output.pop_front(); + + QStringList::Iterator it; + QStringList list; + for (it = output.begin(); it != output.end(); ++it) { + list = QStringList::split(' ', (*it)); + (*it) = list[0].stripWhiteSpace(); + (*it).truncate((*it).find(':')); + } + + return output; +#endif + +#ifdef __FreeBSD__ + QStringList output; + int mib[] = { CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0 }; + char *buf = 0; + int alloc = 0; + struct if_msghdr *ifm, *nextifm; + struct sockaddr_dl *sdl; + char *lim, *next; + size_t needed; + char s[32]; + + if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) + return QStringList(); + + if (alloc < needed) { + buf = new char[needed]; + + if (buf == NULL) + return QStringList(); + + alloc = needed; + } + + if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) + return QStringList(); + + lim = buf + needed; + + next = buf; + while (next < lim) { + ifm = (struct if_msghdr *)next; + if (ifm->ifm_type != RTM_IFINFO) + return QStringList(); + + next += ifm->ifm_msglen; + + // get an interface with a network address + while (next < lim) { + nextifm = (struct if_msghdr *)next; + if (nextifm->ifm_type != RTM_NEWADDR) + break; + + next += nextifm->ifm_msglen; + } + + // if the interface is up + if (ifm->ifm_flags & IFF_UP) { + sdl = (struct sockaddr_dl *)(ifm + 1); + if (sdl->sdl_family != AF_LINK) + continue; + + strncpy(s, sdl->sdl_data, sdl->sdl_nlen); + s[sdl->sdl_nlen] = '\0'; + + output.append(s); + } + } + + if (buf) + delete[] buf; + + return output; +#endif +} diff --git a/ksim/monitors/net/netdialog.h b/ksim/monitors/net/netdialog.h new file mode 100644 index 0000000..b6d7801 --- /dev/null +++ b/ksim/monitors/net/netdialog.h @@ -0,0 +1,85 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#ifndef NETDIALOG_H +#define NETDIALOG_H + +#include <qtabdialog.h> + +class QVBoxLayout; +class QGridLayout; +class QCheckBox; +class QGroupBox; +class QLabel; +class QWidget; +class KComboBox; +class KLineEdit; +class KURLRequester; + +class NetDialog : public QTabDialog +{ + Q_OBJECT + public: + NetDialog(QWidget *parent, const char *name = 0); + ~NetDialog(); + + const QString deviceName() const; + bool timer(); + const QString format() const; + bool commands(); + const QString cCommand() const; + const QString dCommand() const; + bool okClicked() { return m_clicked; } + + public slots: + void setDeviceName(const QString &); + void setShowTimer(bool); + void setFormat(const QString &); + void setShowCommands(bool); + void setCCommand(const QString &); + void setDCommand(const QString &); + + private slots: + void sendClicked(); + + private: + QStringList createList() const; + + bool m_clicked; + QWidget *m_generalTab; + QLabel *m_deviceLabel; + KComboBox *m_deviceCombo; + QGroupBox *m_timerBox; + QCheckBox *m_showTimer; + KLineEdit *m_timerEdit; + QLabel *m_hFormat; + QLabel *m_mFormat; + QLabel *m_sFormat; + QWidget *m_commandTab; + QCheckBox *m_enableCommands; + QLabel *m_cCommand; + KURLRequester *m_connectRequester; + QLabel *m_dCommand; + KURLRequester *m_disconnectRequester; + + QGridLayout *m_generalLayout; + QVBoxLayout *m_timerBoxLayout; + QGridLayout *m_commandLayout; +}; +#endif // NETDIALOG_H diff --git a/ksim/monitors/snmp/Makefile.am b/ksim/monitors/snmp/Makefile.am new file mode 100644 index 0000000..0c922c9 --- /dev/null +++ b/ksim/monitors/snmp/Makefile.am @@ -0,0 +1,16 @@ +kde_module_LTLIBRARIES = ksim_snmp.la +ksim_snmp_la_SOURCES = plugin.cpp view.cpp configpage.cpp configwidget.ui snmp.cpp hostdialogbase.ui hostdialog.cpp value.cpp monitor.cpp \ + monitordialogbase.ui monitordialog.cpp labelmonitor.cpp chartmonitor.cpp \ + identifier.cpp monitorconfig.cpp hostconfig.cpp session.cpp probedialog.cpp snmplib.cpp \ + pdu.cpp proberesultdialogbase.ui proberesultdialog.cpp browsedialogbase.ui browsedialog.cpp \ + walker.cpp + +ksim_snmp_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +ksim_snmp_la_LIBADD = ../../library/libksimcore.la $(LIB_KIO) $(LIBSNMP) + +INCLUDES= -I$(top_srcdir)/ksim/library $(all_includes) + +METASOURCES = AUTO + +mon_DATA = Snmp.desktop +mondir = $(kde_datadir)/ksim/monitors diff --git a/ksim/monitors/snmp/Snmp.desktop b/ksim/monitors/snmp/Snmp.desktop new file mode 100644 index 0000000..b6ceb4c --- /dev/null +++ b/ksim/monitors/snmp/Snmp.desktop @@ -0,0 +1,70 @@ +[Desktop Entry] +Comment=Snmp Status Monitor +Comment[ar]=مراقب Øالة Snmp +Comment[bg]=Мониторинг на Snmp +Comment[bs]=Nadzor SNMP statusa +Comment[ca]=Monitor d'estat snmp +Comment[cs]=Monitor stavu SNMP +Comment[cy]=Monitr Cyflwr Snmp +Comment[da]=Snmp statusovervÃ¥gning +Comment[de]=Statusanzeige für SNMP +Comment[el]=Επόπτης κατάστασης snmp +Comment[eo]=Monitoro por la Snmp-stato +Comment[es]=Monitor de estado de Snmp +Comment[et]=Snmp oleku monitooring +Comment[eu]=Snmp Egoera Begiralea +Comment[fa]=نمایشگر وضعیت Snmp +Comment[fi]=SNPP-tilavalvoja +Comment[fr]=Indicateur d'état snmp +Comment[ga]=Monatóir Stádais SNMP +Comment[hi]=à¤à¤¸à¤à¤¨à¤à¤®à¤ªà¥€ सà¥à¤¥à¤¿à¤¤à¤¿ मॉनीटर +Comment[hu]=Snmp állapotmonitor +Comment[is]=Snmp eftirlitstól +Comment[it]=Controllo di stato SNMP +Comment[ja]=Snmp ステータスモニタ +Comment[ka]=Snmp სტáƒáƒ¢áƒ£áƒ¡áƒ˜áƒ¡ მáƒáƒœáƒ˜áƒ¢áƒáƒ ი +Comment[kk]=SNMP күйін бақылау +Comment[km]=កម្មវិធី​ážáŸ’ážšáž½ážáž–áž·áž“áž·ážáŸ’យ​ស្ážáž¶áž“ភាព Snmp +Comment[lt]=Snmp bÅ«senos stebÄ—tojas +Comment[mk]=Монитор за ÑтатуÑот на Snmp +Comment[nb]=OvervÃ¥kning av status via SNMP +Comment[nds]=SNMP-Statuskieker +Comment[ne]=Snmp सà¥à¤¥à¤¿à¤¤à¤¿ मोनिटर +Comment[nl]=Snmp Statusbewaking +Comment[nn]=Overvaking av status via SNMP +Comment[pa]=Snmp ਹਾਲਤ ਨਿਗਰਾਨ +Comment[pl]=Monitor statusu Snmp +Comment[pt]=Monitor de Estado do SNMP +Comment[pt_BR]=Monitor de estado do SNMP +Comment[ro]=Monitor stare SNMP +Comment[ru]=Монитор ÑоÑтоÑÐ½Ð¸Ñ SNMP +Comment[sk]=Monitor stavu SNMP +Comment[sl]=Nadzornik stanja Snmp +Comment[sr]=Ðадгледање ÑтатуÑа Snmp-а +Comment[sr@Latn]=Nadgledanje statusa Snmp-a +Comment[sv]=Övervakar SNMP-status +Comment[ta]=Snmp நிலை கணà¯à®•à®¾à®£à®¿ +Comment[tg]=Дидабони Ҳолати Snmp +Comment[tr]=Snmp Durum Monitörü +Comment[uk]=Монітор Ñтану мережі (snmp протокол) +Comment[wa]=Corwaitoe di l' estat snmp +Comment[zh_CN]=Snmp 状æ€ç›‘视器 +Comment[zh_TW]=Snmp 狀態監視器 +Icon=network +Name=Snmp +Name[cs]=SNMP +Name[de]=SNMP +Name[ga]=SNMP +Name[hi]=à¤à¤¸à¤à¤¨à¤à¤®à¤ªà¥€ +Name[it]=SNMP +Name[kk]=SNMP +Name[nds]=SNMP +Name[ro]=SNMP +Name[sk]=SNMP +Name[sv]=SNMP +X-KSIM-VERSION=0.1 +X-KSIM-LIBRARY=snmp +X-KSIM-COPYRIGHT=(C) 2003 Simon Hausmann +X-KSIM-EMAIL=hausmann@kde.org +X-KSIM-PREFS=Snmp +X-KSIM-AUTHOR=Simon Hausmann diff --git a/ksim/monitors/snmp/browsedialog.cpp b/ksim/monitors/snmp/browsedialog.cpp new file mode 100644 index 0000000..d196ec8 --- /dev/null +++ b/ksim/monitors/snmp/browsedialog.cpp @@ -0,0 +1,147 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + 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; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "browsedialog.h" + +#include <qlabel.h> + +#include <klistview.h> +#include <kguiitem.h> +#include <klocale.h> +#include <kpushbutton.h> +#include <klineedit.h> + +using namespace KSim::Snmp; + +BrowseDialog::BrowseDialog( const HostConfig &hostConfig, const QString ¤tOid, QWidget *parent, const char *name ) + : BrowseDialogBase( parent, name ), m_host( hostConfig ) +{ + stop->setGuiItem( KGuiItem( i18n( "&Stop" ), "stop" ) ); + + browserContents->setSorting( -1 ); + + selectedObject->setText( currentOid ); + + m_walker = 0; + + baseOids << "1.3.6.1.2" << "1.3.6.1.4"; + nextWalk(); +} + +QString BrowseDialog::selectedObjectIdentifier() const +{ + return selectedObject->text(); +} + +void BrowseDialog::stopAllWalks() +{ + baseOids.clear(); + stopWalker(); +} + +void BrowseDialog::insertBrowseItem( const Walker::Result &result ) +{ + if ( !result.success || + result.data.type() == Value::EndOfMIBView || + result.data.type() == Value::NoSuchInstance || + result.data.type() == Value::NoSuchObject ) { + + nextWalk(); + return; + } + + QListViewItem *i = new QListViewItem( browserContents, browserContents->lastItem(), result.identifierString, result.dataString ); + applyFilter( i ); +} + +void BrowseDialog::applyFilter() +{ + for ( QListViewItem *i = browserContents->firstChild(); + i; i = i->nextSibling() ) + applyFilter( i ); +} + +void BrowseDialog::nextWalk() +{ + stopWalker(); + + if ( baseOids.isEmpty() ) + return; + + QString baseOidString = baseOids.pop(); + Identifier id = Identifier::fromString( baseOidString ); + if ( id.isNull() ) + return; + startWalk( id ); +} + +void BrowseDialog::startWalk( const Identifier &startOid ) +{ + stopWalker(); + + m_walker = new Walker( m_host, startOid, this ); + connect( m_walker, SIGNAL( resultReady( const Walker::Result & ) ), + this, SLOT( insertBrowseItem( const Walker::Result & ) ) ); + connect( m_walker, SIGNAL( finished() ), + this, SLOT( nextWalk() ) ); + + stop->setEnabled( true ); +} + +void BrowseDialog::stopWalker() +{ + if ( !m_walker ) + return; + + disconnect( m_walker, SIGNAL( resultReady( const Walker::Result & ) ), + this, SLOT( insertBrowseItem( const Walker::Result & ) ) ); + disconnect( m_walker, SIGNAL( finished() ), + this, SLOT( nextWalk() ) ); + + m_walker->deleteLater(); + m_walker = 0; + + stop->setEnabled( false ); +} + +void BrowseDialog::objectSelected( QListViewItem *item ) +{ + selectedObject->setText( item->text( 0 ) ); +} + +void BrowseDialog::applyFilter( QListViewItem *item ) +{ + QString filterText = filter->text(); + + if ( filterText.isEmpty() ) { + item->setVisible( true ); + return; + } + + if ( item->text( 0 ).find( filterText, 0 /*index*/, false /*case sensitive*/ ) == -1 ) { + item->setVisible( false ); + return; + } + + item->setVisible( true ); +} + +#include "browsedialog.moc" +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/browsedialog.h b/ksim/monitors/snmp/browsedialog.h new file mode 100644 index 0000000..cb6466a --- /dev/null +++ b/ksim/monitors/snmp/browsedialog.h @@ -0,0 +1,71 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + 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; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef BROWSEDIALOG_H +#define BROWSEDIALOG_H + +#include "browsedialogbase.h" + +#include "hostconfig.h" +#include "identifier.h" +#include "value.h" +#include "snmp.h" +#include "walker.h" + +#include <qvaluestack.h> + +namespace KSim +{ + +namespace Snmp +{ + +class BrowseDialog : public BrowseDialogBase +{ + Q_OBJECT +public: + BrowseDialog( const HostConfig &hostConfig, const QString ¤tOid, QWidget *parent, const char *name = 0 ); + + QString selectedObjectIdentifier() const; + +protected: + virtual void stopAllWalks(); + virtual void applyFilter(); + virtual void objectSelected( QListViewItem *item ); + +private slots: + void insertBrowseItem( const Walker::Result &browseResult ); + void nextWalk(); + +private: + void applyFilter( QListViewItem *item ); + void startWalk( const Identifier &startOid ); + void stopWalker(); + + HostConfig m_host; + Walker *m_walker; + QValueStack<QString> baseOids; +}; + +} +} + +#endif // BROWSEDIALOG_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/browsedialogbase.ui b/ksim/monitors/snmp/browsedialogbase.ui new file mode 100644 index 0000000..17459f8 --- /dev/null +++ b/ksim/monitors/snmp/browsedialogbase.ui @@ -0,0 +1,262 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>KSim::Snmp::BrowseDialogBase</class> +<widget class="KDialog"> + <property name="name"> + <cstring>MyDialog</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>650</width> + <height>532</height> + </rect> + </property> + <property name="caption"> + <string>Browse</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget" row="0" column="0"> + <property name="name"> + <cstring>layout2</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>Filter:</string> + </property> + </widget> + <widget class="QLineEdit"> + <property name="name"> + <cstring>filter</cstring> + </property> + </widget> + <widget class="Line"> + <property name="name"> + <cstring>line1</cstring> + </property> + <property name="frameShape"> + <enum>VLine</enum> + </property> + <property name="frameShadow"> + <enum>Sunken</enum> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + </widget> + <widget class="KPushButton"> + <property name="name"> + <cstring>stop</cstring> + </property> + <property name="text"> + <string>Stop</string> + </property> + </widget> + </hbox> + </widget> + <widget class="KListView" row="1" column="0"> + <column> + <property name="text"> + <string>Object</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Value</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>browserContents</cstring> + </property> + <property name="allColumnsShowFocus"> + <bool>true</bool> + </property> + </widget> + <widget class="QLayoutWidget" row="3" column="0"> + <property name="name"> + <cstring>Layout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <spacer> + <property name="name"> + <cstring>Horizontal Spacing2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonOk</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonCancel</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + </widget> + </hbox> + </widget> + <widget class="QLayoutWidget" row="2" column="0"> + <property name="name"> + <cstring>layout4</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>blah</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Selected object:</string> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>selectedObject</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>textLabel1</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>71</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + </grid> +</widget> +<connections> + <connection> + <sender>buttonOk</sender> + <signal>clicked()</signal> + <receiver>MyDialog</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>buttonCancel</sender> + <signal>clicked()</signal> + <receiver>MyDialog</receiver> + <slot>reject()</slot> + </connection> + <connection> + <sender>stop</sender> + <signal>clicked()</signal> + <receiver>MyDialog</receiver> + <slot>stopAllWalks()</slot> + </connection> + <connection> + <sender>filter</sender> + <signal>textChanged(const QString&)</signal> + <receiver>MyDialog</receiver> + <slot>applyFilter()</slot> + </connection> + <connection> + <sender>browserContents</sender> + <signal>executed(QListViewItem*)</signal> + <receiver>MyDialog</receiver> + <slot>objectSelected(QListViewItem*)</slot> + </connection> +</connections> +<slots> + <slot access="protected">stopAllWalks()</slot> + <slot access="protected">applyFilter()</slot> + <slot access="protected">objectSelected(QListViewItem *)</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>kdialog.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>klistview.h</includehint> +</includehints> +</UI> diff --git a/ksim/monitors/snmp/chartmonitor.cpp b/ksim/monitors/snmp/chartmonitor.cpp new file mode 100644 index 0000000..1a32086 --- /dev/null +++ b/ksim/monitors/snmp/chartmonitor.cpp @@ -0,0 +1,83 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + 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; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +#include "chartmonitor.h" + +#include <kio/global.h> + +using namespace KSim::Snmp; + +ChartMonitor::ChartMonitor( const MonitorConfig &config, QWidget *parent, const char *name ) + : KSim::Chart( true /* displayMeter */, 0, QString::null, parent, name ), + m_lastValue( 0 ), m_config( config ), m_firstSampleReceived( false ) +{ + setTitle( m_config.name ); + disableAutomaticUpdates(); +} + +void ChartMonitor::setData( const Value &data ) +{ + Q_UINT64 currentValue = convertToInt( data ); + + if ( data.isCounterType() ) { + int diff = currentValue - m_lastValue; + + if ( !m_firstSampleReceived ) { + diff = 0; + m_firstSampleReceived = true; + } + + m_lastValue = currentValue; + currentValue = diff; + } + + // move the graph and add the new sample then + updateDisplay(); + setValue( currentValue ); + if ( m_config.displayCurrentValueInline ) { + Q_UINT64 bytesPerSec = currentValue / ( m_config.refreshInterval.seconds + m_config.refreshInterval.minutes * 60 ); + setText( KIO::convertSize( bytesPerSec ), 0 ); + } +} + +Q_UINT64 ChartMonitor::convertToInt( const Value &data ) +{ + switch ( data.type() ) { + case Value::TimeTicks: + case Value::Int: return data.toInt(); + case Value::Gauge: + case Value::Counter: + case Value::UInt: return data.toUInt(); + case Value::Counter64: return data.toCounter64(); + case Value::Double: // ### not sure what to do here... + case Value::ByteArray: + case Value::Oid: // ### could treat this as a sort of hyperlink... hmm + case Value::IpAddress: + case Value::NoSuchObject: + case Value::NoSuchInstance: + case Value::EndOfMIBView: + case Value::Invalid: + case Value::Null: return 0; + } + return 0; +} + +#include "chartmonitor.moc" + +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/chartmonitor.h b/ksim/monitors/snmp/chartmonitor.h new file mode 100644 index 0000000..30a58ad --- /dev/null +++ b/ksim/monitors/snmp/chartmonitor.h @@ -0,0 +1,54 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + 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; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +#ifndef CHARTMONITOR_H +#define CHARTMONITOR_H + +#include "chart.h" +#include "monitor.h" + +namespace KSim +{ + +namespace Snmp +{ + +class ChartMonitor : public KSim::Chart +{ + Q_OBJECT +public: + ChartMonitor( const MonitorConfig &config, QWidget *parent, const char *name = 0 ); + +public slots: + void setData( const Value &data ); + +private: + Q_UINT64 m_lastValue; + MonitorConfig m_config; + bool m_firstSampleReceived; + + static Q_UINT64 convertToInt( const Value &data ); +}; + +} + +} + +#endif // CHARTMONITOR_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/configpage.cpp b/ksim/monitors/snmp/configpage.cpp new file mode 100644 index 0000000..d15d606 --- /dev/null +++ b/ksim/monitors/snmp/configpage.cpp @@ -0,0 +1,313 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + 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; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "configpage.h" +#include "plugin.h" + +#include "configwidget.h" +#include "hostdialog.h" +#include "monitordialog.h" + +#include <qlayout.h> +#include <qgroupbox.h> +#include <qpushbutton.h> + +#include <kconfig.h> +#include <klistview.h> +#include <kmessagebox.h> +#include <klocale.h> + +using namespace KSim::Snmp; + +static bool listViewHasSelection( QListView *lv ) +{ + for ( QListViewItem *i = lv->firstChild(); i; i = i->itemBelow() ) + if ( i->isSelected() ) + return true; + return false; +} + +ConfigPage::ConfigPage( Plugin *parent, const char *name ) + : KSim::PluginPage( parent, name ) +{ + ( new QVBoxLayout( this ) )->setAutoAdd( true ); + + m_page = new ConfigWidget( this ); + + connect( m_page->addHost, SIGNAL( clicked() ), + this, SLOT( addNewHost() ) ); + connect( m_page->modifyHost, SIGNAL( clicked() ), + this, SLOT( modifyHost() ) ); + connect( m_page->removeHost, SIGNAL( clicked() ), + this, SLOT( removeHost() ) ); + + connect( m_page->addMonitor, SIGNAL( clicked() ), + this, SLOT( addNewMonitor() ) ); + connect( m_page->modifyMonitor, SIGNAL( clicked() ), + this, SLOT( modifyMonitor() ) ); + connect( m_page->removeMonitor, SIGNAL( clicked() ), + this, SLOT( removeMonitor() ) ); + + connect( m_page->hosts, SIGNAL( selectionChanged() ), + this, SLOT( disableOrEnableSomeWidgets() ) ); + connect( m_page->monitors, SIGNAL( selectionChanged() ), + this, SLOT( disableOrEnableSomeWidgets() ) ); +} + +ConfigPage::~ConfigPage() +{ +} + +void ConfigPage::saveConfig() +{ + KConfig &cfg = *config(); + + // collect garbage + removeAllHostGroups(); + removeAllMonitorGroups(); + + QStringList hosts = m_hosts.save( cfg ); + QStringList monitors = m_monitors.save( cfg ); + + cfg.setGroup( "General" ); + cfg.writeEntry( "Hosts", hosts ); + cfg.writeEntry( "Monitors", monitors ); +} + +void ConfigPage::readConfig() +{ + KConfig &cfg = *config(); + + cfg.setGroup( "General" ); + QStringList hosts = cfg.readListEntry( "Hosts" ); + QStringList monitors = cfg.readListEntry( "Monitors" ); + + m_hosts.load( cfg, hosts ); + m_monitors.load( cfg, monitors, m_hosts ); + + fillGui(); +} + +void ConfigPage::addNewHost() +{ + HostDialog dlg( this ); + if ( dlg.exec() ) { + HostConfig src = dlg.settings(); + m_hosts.insert( src.name, src ); + + ( void )new HostItem( m_page->hosts, src ); + } + + disableOrEnableSomeWidgets(); +} + +void ConfigPage::modifyHost() +{ + HostItem *currentItem = dynamic_cast<HostItem *>( m_page->hosts->currentItem() ); + if ( !currentItem ) + return; + + HostConfigMap::Iterator hostIt = m_hosts.find( currentItem->text( 0 ) ); + if ( hostIt == m_hosts.end() ) + return; + + HostDialog dlg( *hostIt, this ); + if ( dlg.exec() ) { + HostConfig newHost = dlg.settings(); + + if ( newHost.name != hostIt.key() ) { + m_hosts.remove( hostIt ); + hostIt = m_hosts.insert( newHost.name, newHost ); + } else + *hostIt = newHost; + + currentItem->setFromHostConfig( newHost ); + } +} + +void ConfigPage::removeHost() +{ + HostItem *currentItem = dynamic_cast<HostItem *>( m_page->hosts->currentItem() ); + if ( !currentItem ) + return; + + HostConfigMap::Iterator hostIt = m_hosts.find( currentItem->text( 0 ) ); + if ( hostIt == m_hosts.end() ) + return; + + QStringList monitors = monitorsForHost( *hostIt ); + if ( !monitors.isEmpty() ) { + int answer = KMessageBox::warningContinueCancelList( + this, + i18n( "This host has the following monitor associated. Do you really want to delete this host entry?", + "This host has the following %n monitors associated. Do you really want to delete this host entry?", + monitors.count() ), + monitors, + i18n( "Delete Host Entry" ), + i18n( "Delete" ) ); + + if ( answer != KMessageBox::Continue ) + return; + + removeMonitors( monitors ); + } + + m_hosts.remove( hostIt ); + delete currentItem; + + disableOrEnableSomeWidgets(); +} + +void ConfigPage::addNewMonitor() +{ + MonitorDialog dlg( m_hosts, this ); + if ( dlg.exec() ) { + MonitorConfig monitor = dlg.monitorConfig(); + m_monitors.insert( monitor.name, monitor ); + + ( void )new MonitorItem( m_page->monitors, monitor ); + } +} + +void ConfigPage::modifyMonitor() +{ + MonitorItem *currentItem = dynamic_cast<MonitorItem *>( m_page->monitors->currentItem() ); + if ( !currentItem ) + return; + + MonitorConfigMap::Iterator monitorIt = m_monitors.find( currentItem->text( 0 ) ); + if ( monitorIt == m_monitors.end() ) + return; + + MonitorDialog dlg( *monitorIt, m_hosts, this ); + if ( dlg.exec() ) { + MonitorConfig newMonitor = dlg.monitorConfig(); + + if ( newMonitor.name != monitorIt.key() ) { + m_monitors.remove( monitorIt ); + monitorIt = m_monitors.insert( newMonitor.name, newMonitor ); + } else + *monitorIt = newMonitor; + + currentItem->setFromMonitor( newMonitor ); + } +} + +void ConfigPage::removeMonitor() +{ + MonitorItem *currentItem = dynamic_cast<MonitorItem *>( m_page->monitors->currentItem() ); + if ( !currentItem ) + return; + + MonitorConfigMap::Iterator monitorIt = m_monitors.find( currentItem->text( 0 ) ); + if ( monitorIt == m_monitors.end() ) + return; + + m_monitors.remove( monitorIt ); + delete currentItem; +} + +void ConfigPage::disableOrEnableSomeWidgets() +{ + bool hostSelected = listViewHasSelection( m_page->hosts ); + bool monitorSelected = listViewHasSelection( m_page->monitors ); + + m_page->modifyHost->setEnabled( hostSelected ); + m_page->removeHost->setEnabled( hostSelected ); + + m_page->modifyMonitor->setEnabled( monitorSelected ); + m_page->removeMonitor->setEnabled( monitorSelected ); + + m_page->monitorGroup->setEnabled( !m_hosts.isEmpty() ); +} + +void ConfigPage::removeMonitors( QStringList monitors ) +{ + for ( QStringList::ConstIterator it = monitors.begin(); + it != monitors.end(); ++it ) + m_monitors.remove( *it ); + + QListViewItem *item = m_page->monitors->firstChild(); + while ( item ) { + QListViewItem *nextItem = item->itemBelow(); + + for ( QStringList::Iterator it = monitors.begin(); + it != monitors.end(); ++it ) + if ( item->text( 0 ) == *it ) { + + monitors.remove( it ); + + delete item; + + break; + } + + item = nextItem; + } +} + +void ConfigPage::removeAllHostGroups() +{ + removeConfigGroups( "Host " ); +} + +void ConfigPage::removeAllMonitorGroups() +{ + removeConfigGroups( "Monitor " ); +} + +void ConfigPage::removeConfigGroups( const QString &prefix ) +{ + KConfig &cfg = *config(); + + QStringList groups = cfg.groupList(); + for ( QStringList::ConstIterator it = groups.begin(); it != groups.end(); ++it ) + if ( ( *it ).startsWith( prefix ) ) + cfg.deleteGroup( *it, true /* deep */ ); +} + +void ConfigPage::fillGui() +{ + m_page->hosts->clear(); + m_page->monitors->clear(); + + for ( HostConfigMap::ConstIterator it = m_hosts.begin(); it != m_hosts.end(); ++it ) + ( void )new HostItem( m_page->hosts, *it ); + + for ( MonitorConfigMap::ConstIterator it = m_monitors.begin(); it != m_monitors.end(); ++it ) + ( void )new MonitorItem( m_page->monitors, *it ); + + disableOrEnableSomeWidgets(); +} + +QStringList ConfigPage::monitorsForHost( const HostConfig &host ) const +{ + QStringList monitors; + + for ( MonitorConfigMap::ConstIterator it = m_monitors.begin(); + it != m_monitors.end(); ++it ) + if ( ( *it ).host == host ) + monitors << ( *it ).name; + + return monitors; +} + +#include "configpage.moc" +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/configpage.h b/ksim/monitors/snmp/configpage.h new file mode 100644 index 0000000..42c7579 --- /dev/null +++ b/ksim/monitors/snmp/configpage.h @@ -0,0 +1,120 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + 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; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef CONFIGPAGE_H +#define CONFIGPAGE_H + +#include <pluginmodule.h> +#include <klistview.h> + +#include "monitorconfig.h" +#include "hostconfig.h" + +namespace KSim +{ + +namespace Snmp +{ + +class HostItem : public QListViewItem +{ +public: + HostItem( QListView *parent, const KSim::Snmp::HostConfig &src ) + : QListViewItem( parent, QString::null, QString::null, QString::null ) + { + setFromHostConfig( src ); + } + + HostItem( QListView *parent ) + : QListViewItem( parent, QString::null, QString::null, QString::null ) + {} + + void setFromHostConfig( const KSim::Snmp::HostConfig &src ) + { + setText( 0, src.name ); + setText( 1, QString::number( src.port ) ); + setText( 2, snmpVersionToString( src.version ) ); + } +}; + +class MonitorItem : public QListViewItem +{ +public: + MonitorItem( QListView *parent, const KSim::Snmp::MonitorConfig &monitor ) + : QListViewItem( parent, QString::null, QString::null, QString::null ) + { + setFromMonitor( monitor ); + } + + MonitorItem( QListView *parent ) + : QListViewItem( parent, QString::null, QString::null, QString::null ) + {} + + void setFromMonitor( const KSim::Snmp::MonitorConfig &monitor ) + { + setText( 0, monitor.name ); + setText( 1, monitorDisplayTypeToString( monitor.display ) ); + } +}; + +class ConfigWidget; +class Plugin; + +class ConfigPage : public KSim::PluginPage +{ + Q_OBJECT +public: + ConfigPage( Plugin *parent, const char *name ); + ~ConfigPage(); + + virtual void saveConfig(); + virtual void readConfig(); + +private slots: + void addNewHost(); + void modifyHost(); + void removeHost(); + void addNewMonitor(); + void modifyMonitor(); + void removeMonitor(); + + void disableOrEnableSomeWidgets(); + +private: + void removeMonitors( QStringList monitors ); + + void removeAllHostGroups(); + void removeAllMonitorGroups(); + void removeConfigGroups( const QString &prefix ); + void fillGui(); + + QStringList monitorsForHost( const HostConfig &host ) const; + + ConfigWidget *m_page; + KSim::Snmp::HostConfigMap m_hosts; + KSim::Snmp::MonitorConfigMap m_monitors; +}; + +} + +} + +#endif // CONFIGPAGE_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/configure.in.in b/ksim/monitors/snmp/configure.in.in new file mode 100644 index 0000000..2d266d7 --- /dev/null +++ b/ksim/monitors/snmp/configure.in.in @@ -0,0 +1,40 @@ +AC_ARG_WITH(snmp, + [AC_HELP_STRING(--with-snmp, + [enable support for SNMP @<:@default=check@:>@])], + [], with_snmp=check) + +enable_snmp=no +if test "x$with_snmp" != xno; then + KDE_CHECK_HEADER( net-snmp/library/snmp_api.h, + [ have_netsnmp_h=yes ], [ have_netsnmp_h=no ], + [ #include <net-snmp/net-snmp-config.h> + #include <net-snmp/types.h> + ] + ) + + if test "$have_netsnmp_h" = yes; then + KDE_CHECK_LIB( netsnmp, snmp_sess_init, [ + AC_SUBST( LIBSNMP, "-lnetsnmp" ) + enable_snmp=yes + ], [], [] ) + fi + + if test "$enable_snmp" != yes; then + AC_MSG_CHECKING([if libnetsnmp needs -lcrypto]) + + dnl use a different symbol to prevent autoconf from caching + KDE_CHECK_LIB( netsnmp, snmp_open, [ + AC_SUBST( LIBSNMP, "-lnetsnmp -lcrypto" ) + enable_snmp=yes + AC_MSG_RESULT(yes) + ], [ + AC_MSG_RESULT(no) + ], [-lcrypto] ) + fi + + if test "x$with_snmp" != xcheck && test "x$enable_snmp" != xyes; then + AC_MSG_ERROR([--with-snmp was given, but test for net-snmp failed]) + fi +fi + +AM_CONDITIONAL(include_ksim_monitors_snmp, test "x$enable_snmp" = xyes) diff --git a/ksim/monitors/snmp/configwidget.ui b/ksim/monitors/snmp/configwidget.ui new file mode 100644 index 0000000..c121184 --- /dev/null +++ b/ksim/monitors/snmp/configwidget.ui @@ -0,0 +1,215 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>KSim::Snmp::ConfigWidget</class> +<widget class="QWidget"> + <property name="name"> + <cstring>ConfigWidget</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>740</width> + <height>597</height> + </rect> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QGroupBox"> + <property name="name"> + <cstring>hostGroup</cstring> + </property> + <property name="title"> + <string>SNMP Hosts</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QPushButton" row="1" column="3"> + <property name="name"> + <cstring>removeHost</cstring> + </property> + <property name="text"> + <string>Remove</string> + </property> + </widget> + <widget class="QPushButton" row="1" column="2"> + <property name="name"> + <cstring>modifyHost</cstring> + </property> + <property name="text"> + <string>Modify...</string> + </property> + </widget> + <widget class="QPushButton" row="1" column="1"> + <property name="name"> + <cstring>addHost</cstring> + </property> + <property name="text"> + <string>Add...</string> + </property> + </widget> + <widget class="KListView" row="0" column="0" rowspan="1" colspan="4"> + <column> + <property name="text"> + <string>Host</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Port</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Version</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>hosts</cstring> + </property> + <property name="allColumnsShowFocus"> + <bool>true</bool> + </property> + </widget> + <spacer row="1" column="0"> + <property name="name"> + <cstring>spacer1</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>141</width> + <height>20</height> + </size> + </property> + </spacer> + </grid> + </widget> + <widget class="QGroupBox"> + <property name="name"> + <cstring>monitorGroup</cstring> + </property> + <property name="title"> + <string>SNMP Monitors</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QPushButton" row="1" column="1"> + <property name="name"> + <cstring>addMonitor</cstring> + </property> + <property name="text"> + <string>Add...</string> + </property> + </widget> + <widget class="QPushButton" row="1" column="2"> + <property name="name"> + <cstring>modifyMonitor</cstring> + </property> + <property name="text"> + <string>Modify...</string> + </property> + </widget> + <widget class="QPushButton" row="1" column="3"> + <property name="name"> + <cstring>removeMonitor</cstring> + </property> + <property name="text"> + <string>Remove</string> + </property> + </widget> + <spacer row="1" column="0"> + <property name="name"> + <cstring>spacer2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>121</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="KListView" row="0" column="0" rowspan="1" colspan="4"> + <column> + <property name="text"> + <string>Name</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Type</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>monitors</cstring> + </property> + <property name="allColumnsShowFocus"> + <bool>true</bool> + </property> + </widget> + </grid> + </widget> + </vbox> +</widget> +<tabstops> + <tabstop>hosts</tabstop> + <tabstop>addHost</tabstop> + <tabstop>modifyHost</tabstop> + <tabstop>removeHost</tabstop> + <tabstop>monitors</tabstop> + <tabstop>addMonitor</tabstop> + <tabstop>modifyMonitor</tabstop> + <tabstop>removeMonitor</tabstop> +</tabstops> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>klistview.h</includehint> + <includehint>klistview.h</includehint> +</includehints> +</UI> diff --git a/ksim/monitors/snmp/hostconfig.cpp b/ksim/monitors/snmp/hostconfig.cpp new file mode 100644 index 0000000..1b96541 --- /dev/null +++ b/ksim/monitors/snmp/hostconfig.cpp @@ -0,0 +1,152 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + 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; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "hostconfig.h" + +#include <kstringhandler.h> + +#include <netdb.h> + +using namespace KSim::Snmp; + +static int defaultSnmpPort() +{ + servent *ent = getservbyname( "snmp", 0 ); + if ( !ent ) + return 161; + return ent->s_port; +} + +bool HostConfig::load( KConfigBase &config ) +{ + name = config.readEntry( "Host" ); + if ( name.isEmpty() ) + return false; + + port = config.readNumEntry( "Port", defaultSnmpPort() ); + + bool ok = false; + version = stringToSnmpVersion( config.readEntry( "Version" ), &ok ); + if ( !ok ) + return false; + + if ( version != SnmpVersion3 ) { + community = config.readEntry( "Community" ); + return true; + } + + securityName = config.readEntry( "SecurityName" ); + + securityLevel = stringToSecurityLevel( config.readEntry( "SecurityLevel" ), &ok ); + if ( !ok ) + return false; + + if ( securityLevel == NoAuthPriv ) + return true; + + authentication.protocol = stringToAuthenticationProtocol( config.readEntry( "AuthType" ), &ok ); + if ( !ok ) + return false; + authentication.key = KStringHandler::obscure( config.readEntry( "AuthPassphrase" ) ); + + if ( securityLevel == AuthNoPriv ) + return true; + + privacy.protocol = stringToPrivacyProtocol( config.readEntry( "PrivType" ), &ok ); + if ( !ok ) + return false; + privacy.key = KStringHandler::obscure( config.readEntry( "PrivPassphrase" ) ); + + return true; +} + +void HostConfig::save( KConfigBase &config ) const +{ + if ( isNull() ) + return; + + config.writeEntry( "Host", name ); + if ( port != 0 ) + config.writeEntry( "Port", port ); + + config.writeEntry( "Version", snmpVersionToString( version ) ); + + if ( version != SnmpVersion3 ) { + writeIfNotEmpty( config, "Community", community ); + return; + } + + writeIfNotEmpty( config, "SecurityName", securityName ); + + config.writeEntry( "SecurityLevel", securityLevelToString( securityLevel ) ); + + if ( securityLevel == NoAuthPriv ) + return; + + writeIfNotEmpty( config, "AuthType", authenticationProtocolToString( authentication.protocol ) ); + writeIfNotEmpty( config, "AuthPassphrase", KStringHandler::obscure( authentication.key ) ); + + if ( securityLevel == AuthNoPriv ) + return; + + writeIfNotEmpty( config, "PrivType", privacyProtocolToString( privacy.protocol ) ); + writeIfNotEmpty( config, "PrivPassphrase", KStringHandler::obscure( privacy.key ) ); +} + +void HostConfig::writeIfNotEmpty( KConfigBase &config, const QString &name, const QString &value ) +{ + if ( value.isEmpty() ) + return; + + config.writeEntry( name, value ); +} + +void HostConfigMap::load( KConfigBase &config, const QStringList &hosts ) +{ + clear(); + + for ( QStringList::ConstIterator it = hosts.begin(); it != hosts.end(); ++it ) { + config.setGroup( "Host " + *it ); + + HostConfig src; + if ( !src.load( config ) ) + continue; + + insert( *it, src ); + } +} + +QStringList HostConfigMap::save( KConfigBase &config ) const +{ + QStringList hostList; + + for ( ConstIterator it = begin(); it != end(); ++it ) { + QString host = it.key(); + + hostList << host; + + config.setGroup( "Host " + host ); + ( *it ).save( config ); + } + + return hostList; +} + +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/hostconfig.h b/ksim/monitors/snmp/hostconfig.h new file mode 100644 index 0000000..d19de9b --- /dev/null +++ b/ksim/monitors/snmp/hostconfig.h @@ -0,0 +1,86 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + 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; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef HOSTCONFIG_H +#define HOSTCONFIG_H + +#include "snmp.h" + +namespace KSim +{ + +namespace Snmp +{ + +struct HostConfig +{ + HostConfig() {} + HostConfig( KConfigBase &config ) + { load( config ); } + + QString name; // hostname + ushort port; + + SnmpVersion version; + + QString community; + + QString securityName; + + SecurityLevel securityLevel; + + struct + { + AuthenticationProtocol protocol; + QString key; + } authentication; + struct + { + PrivacyProtocol protocol; + QString key; + } privacy; + + bool load( KConfigBase &config ); + void save( KConfigBase &config ) const; + + bool isNull() const { return name.isEmpty(); } + + bool operator==( const HostConfig &rhs ) const + { return name == rhs.name; } + +private: + static void writeIfNotEmpty( KConfigBase &config, const QString &name, const QString &value ); +}; + +struct HostConfigMap : public QMap< QString, HostConfig > +{ + HostConfigMap() {} + HostConfigMap( const QMap< QString, HostConfig > &rhs ) + : QMap< QString, HostConfig >( rhs ) {} + + void load( KConfigBase &config, const QStringList &hosts ); + QStringList save( KConfigBase &config ) const; +}; + +} +} + +#endif // HOSTCONFIG_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/hostdialog.cpp b/ksim/monitors/snmp/hostdialog.cpp new file mode 100644 index 0000000..a1ccdc3 --- /dev/null +++ b/ksim/monitors/snmp/hostdialog.cpp @@ -0,0 +1,193 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + 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; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "hostdialog.h" +#include "probedialog.h" +#include "proberesultdialog.h" + +#include <qcombobox.h> +#include <qwidgetstack.h> +#include <klineedit.h> +#include <qlabel.h> +#include <qpushbutton.h> +#include <qspinbox.h> + +#include <klocale.h> +#include <kmessagebox.h> + +#include <assert.h> + +using namespace KSim::Snmp; + +HostDialog::HostDialog( QWidget *parent, const char *name ) + : HostDialogBase( parent, name ) +{ + init(); + port->setValue( 161 ); +} + +HostDialog::HostDialog( const HostConfig &src, QWidget *parent, const char *name ) + : HostDialogBase( parent, name ) +{ + init( src ); +} + +HostConfig HostDialog::settings() const +{ + HostConfig result; + + result.name = hostName->text(); + result.port = port->value(); + + result.version = stringToSnmpVersion( snmpVersion->currentText() ); + if ( result.version != SnmpVersion3 ) { + result.community = communityString->text(); + } + + result.securityName = securityName->text(); + + result.securityLevel = stringToSecurityLevel( securityLevel->currentText() ); + + if ( result.securityLevel == NoAuthPriv ) + return result; + + result.authentication.protocol = stringToAuthenticationProtocol( authenticationType->currentText() ); + result.authentication.key = authenticationPassphrase->text(); + + if ( result.securityLevel == AuthNoPriv ) + return result; + + result.privacy.protocol = stringToPrivacyProtocol( privacyType->currentText() ); + result.privacy.key = privacyPassphrase->text(); + + return result; +} + +void HostDialog::showSnmpAuthenticationDetailsForVersion( const QString &versionStr ) +{ + bool ok = false; + SnmpVersion version = stringToSnmpVersion( versionStr, &ok ); + assert( ok ); + + authenticationDetails->raiseWidget( version == SnmpVersion3 ? snmpV3Page : snmpV1Page ); +} + +void HostDialog::enableDisabledAuthenticationAndPrivacyElementsForSecurityLevel( const QString &levelStr ) +{ + bool ok = false; + SecurityLevel level = stringToSecurityLevel( levelStr, &ok ); + assert( ok ); + + bool enableAuthentication = level != NoAuthPriv; + bool enablePrivacy = level == AuthPriv; + + authenticationTypeLabel->setEnabled( enableAuthentication ); + authenticationType->setEnabled( enableAuthentication ); + authenticationPassphraseLabel->setEnabled( enableAuthentication ); + authenticationPassphrase->setEnabled( enableAuthentication ); + + privacyTypeLabel->setEnabled( enablePrivacy ); + privacyType->setEnabled( enablePrivacy ); + privacyPassphraseLabel->setEnabled( enablePrivacy ); + privacyPassphrase->setEnabled( enablePrivacy ); +} + +void HostDialog::checkValidity() +{ + bool enableOk = true; + bool ok = false; + SnmpVersion version = stringToSnmpVersion( snmpVersion->currentText(), &ok ); + assert( ok ); + + enableOk &= !hostName->text().isEmpty(); + + if ( version == SnmpVersion3 ) + enableOk &= !securityName->text().isEmpty(); + else + enableOk &= !communityString->text().isEmpty(); + + buttonOk->setEnabled( enableOk ); + testHostButton->setEnabled( enableOk ); +} + +void HostDialog::testHost() +{ + ProbeDialog dlg( settings(), this ); + if ( dlg.exec() ) { + ProbeDialog::ProbeResultList results = dlg.probeResults(); + + ProbeResultDialog resultDlg( settings(), results, this ); + resultDlg.exec(); + } +} + +void HostDialog::init( const HostConfig &src ) +{ + // hide these, there's nothing to choose right now. might be that + // net-snmp will support different privacy types in the future, but + // apparently not now. + privacyTypeLabel->hide(); + privacyType->hide(); + + snmpVersion->insertStringList( allSnmpVersions() ); + securityLevel->insertStringList( allSecurityLevels() ); + authenticationType->insertStringList( allAuthenticationProtocols() ); + privacyType->insertStringList( allPrivacyProtocols() ); + + if ( !src.isNull() ) + loadSettingsFromHostConfig( src ); + + showSnmpAuthenticationDetailsForVersion( snmpVersion->currentText() ); + enableDisabledAuthenticationAndPrivacyElementsForSecurityLevel( securityLevel->currentText() ); + checkValidity(); +} + +void HostDialog::loadSettingsFromHostConfig( const HostConfig &src ) +{ + hostName->setText( src.name ); + port->setValue( src.port ); + + snmpVersion->setCurrentItem( allSnmpVersions().findIndex( snmpVersionToString( src.version ) ) ); + + if ( src.version != SnmpVersion3 ) { + communityString->setText( src.community ); + return; + } + + securityName->setText( src.securityName ); + + securityLevel->setCurrentItem( allSecurityLevels().findIndex( securityLevelToString( src.securityLevel ) ) ); + + if ( src.securityLevel == NoAuthPriv ) + return; + + authenticationType->setCurrentItem( allAuthenticationProtocols().findIndex( authenticationProtocolToString( src.authentication.protocol ) ) ); + authenticationPassphrase->setText( src.authentication.key ); + + if ( src.securityLevel == AuthNoPriv ) + return; + + privacyType->setCurrentItem( allPrivacyProtocols().findIndex( privacyProtocolToString( src.privacy.protocol ) ) ); + privacyPassphrase->setText( src.privacy.key ); +} + +#include "hostdialog.moc" + +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/hostdialog.h b/ksim/monitors/snmp/hostdialog.h new file mode 100644 index 0000000..e296b7b --- /dev/null +++ b/ksim/monitors/snmp/hostdialog.h @@ -0,0 +1,59 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + 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; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef HOSTDIALOG_H +#define HOSTDIALOG_H + +#include "hostdialogbase.h" +#include "hostconfig.h" +#include "probedialog.h" + +namespace KSim +{ + +namespace Snmp +{ + +class HostDialog : public HostDialogBase +{ + Q_OBJECT +public: + HostDialog( QWidget *parent, const char *name = 0 ); + HostDialog( const HostConfig &src, QWidget *parent, const char *name = 0 ); + + HostConfig settings() const; + +private slots: + void showSnmpAuthenticationDetailsForVersion( const QString &versionStr ); + void enableDisabledAuthenticationAndPrivacyElementsForSecurityLevel( const QString &levelStr ); + void checkValidity(); + void testHost(); + +private: + void init( const HostConfig &src = HostConfig() ); + void loadSettingsFromHostConfig( const HostConfig &src ); +}; + +} + +} + +#endif // HOSTDIALOG_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/hostdialogbase.ui b/ksim/monitors/snmp/hostdialogbase.ui new file mode 100644 index 0000000..1ee9ee4 --- /dev/null +++ b/ksim/monitors/snmp/hostdialogbase.ui @@ -0,0 +1,526 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>KSim::Snmp::HostDialogBase</class> +<comment>Much thanks to Frerich for hints/advice on the GUI design</comment> +<author>Simon Hausmann</author> +<widget class="KDialog"> + <property name="name"> + <cstring>HostDialogBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>559</width> + <height>454</height> + </rect> + </property> + <property name="caption"> + <string>Configure Host</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel2</cstring> + </property> + <property name="frameShape"> + <enum>NoFrame</enum> + </property> + <property name="frameShadow"> + <enum>Plain</enum> + </property> + <property name="text"> + <string>&Hostname:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>hostName</cstring> + </property> + </widget> + <widget class="KLineEdit" row="0" column="1"> + <property name="name"> + <cstring>hostName</cstring> + </property> + </widget> + <widget class="QLabel" row="0" column="2"> + <property name="name"> + <cstring>textLabel3</cstring> + </property> + <property name="text"> + <string>&Port:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>port</cstring> + </property> + </widget> + <widget class="QSpinBox" row="0" column="3"> + <property name="name"> + <cstring>port</cstring> + </property> + <property name="maxValue"> + <number>65535</number> + </property> + <property name="minValue"> + <number>1</number> + </property> + </widget> + <spacer row="0" column="4"> + <property name="name"> + <cstring>spacer2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>91</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QButtonGroup" row="1" column="0" rowspan="1" colspan="5"> + <property name="name"> + <cstring>buttonGroup2</cstring> + </property> + <property name="title"> + <string>Authentication Details</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QWidgetStack" row="2" column="0" rowspan="1" colspan="3"> + <property name="name"> + <cstring>authenticationDetails</cstring> + </property> + <widget class="QWidget"> + <property name="name"> + <cstring>snmpV1Page</cstring> + </property> + <attribute name="id"> + <number>0</number> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel5</cstring> + </property> + <property name="text"> + <string>&Community String:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>communityString</cstring> + </property> + </widget> + <spacer row="1" column="1"> + <property name="name"> + <cstring>spacer4</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>41</height> + </size> + </property> + </spacer> + <spacer row="0" column="2"> + <property name="name"> + <cstring>spacer3</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>160</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="KLineEdit" row="0" column="1"> + <property name="name"> + <cstring>communityString</cstring> + </property> + <property name="echoMode"> + <enum>Password</enum> + </property> + </widget> + </grid> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>snmpV3Page</cstring> + </property> + <attribute name="id"> + <number>1</number> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel6</cstring> + </property> + <property name="text"> + <string>S&ecurity name:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>securityName</cstring> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>textLabel7</cstring> + </property> + <property name="text"> + <string>Security &level:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>securityLevel</cstring> + </property> + </widget> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>authenticationTypeLabel</cstring> + </property> + <property name="text"> + <string>&Authentication type:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>authenticationType</cstring> + </property> + </widget> + <widget class="QLabel" row="4" column="0"> + <property name="name"> + <cstring>privacyTypeLabel</cstring> + </property> + <property name="text"> + <string>P&rivacy type:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>privacyType</cstring> + </property> + </widget> + <widget class="QLabel" row="5" column="0"> + <property name="name"> + <cstring>privacyPassphraseLabel</cstring> + </property> + <property name="text"> + <string>Priva&cy passphrase:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>privacyPassphrase</cstring> + </property> + </widget> + <widget class="QLabel" row="3" column="0"> + <property name="name"> + <cstring>authenticationPassphraseLabel</cstring> + </property> + <property name="text"> + <string>Authentication &passphrase:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>authenticationPassphrase</cstring> + </property> + </widget> + <spacer row="3" column="2"> + <property name="name"> + <cstring>spacer5</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>71</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="KLineEdit" row="0" column="1"> + <property name="name"> + <cstring>securityName</cstring> + </property> + </widget> + <widget class="QComboBox" row="4" column="1"> + <property name="name"> + <cstring>privacyType</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + </widget> + <widget class="KLineEdit" row="5" column="1"> + <property name="name"> + <cstring>privacyPassphrase</cstring> + </property> + <property name="echoMode"> + <enum>Password</enum> + </property> + </widget> + <widget class="QComboBox" row="1" column="1"> + <property name="name"> + <cstring>securityLevel</cstring> + </property> + </widget> + <widget class="QComboBox" row="2" column="1"> + <property name="name"> + <cstring>authenticationType</cstring> + </property> + </widget> + <widget class="KLineEdit" row="3" column="1"> + <property name="name"> + <cstring>authenticationPassphrase</cstring> + </property> + <property name="echoMode"> + <enum>Password</enum> + </property> + </widget> + <spacer row="6" column="1"> + <property name="name"> + <cstring>spacer7</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </grid> + </widget> + </widget> + <widget class="Line" row="1" column="0" rowspan="1" colspan="3"> + <property name="name"> + <cstring>line3</cstring> + </property> + <property name="frameShape"> + <enum>HLine</enum> + </property> + <property name="frameShadow"> + <enum>Sunken</enum> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel2_2</cstring> + </property> + <property name="text"> + <string>&SNMP version:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>snmpVersion</cstring> + </property> + </widget> + <widget class="QComboBox" row="0" column="1"> + <property name="name"> + <cstring>snmpVersion</cstring> + </property> + </widget> + <spacer row="0" column="2"> + <property name="name"> + <cstring>spacer8</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>351</width> + <height>20</height> + </size> + </property> + </spacer> + </grid> + </widget> + <widget class="Line" row="2" column="0" rowspan="1" colspan="5"> + <property name="name"> + <cstring>line2</cstring> + </property> + <property name="frameShape"> + <enum>HLine</enum> + </property> + <property name="frameShadow"> + <enum>Sunken</enum> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + </widget> + <widget class="QLayoutWidget" row="3" column="0" rowspan="1" colspan="5"> + <property name="name"> + <cstring>layout2</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QPushButton"> + <property name="name"> + <cstring>testHostButton</cstring> + </property> + <property name="text"> + <string>Test Host...</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Horizontal Spacing2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>220</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonOk</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonCancel</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + </widget> + </hbox> + </widget> + </grid> +</widget> +<connections> + <connection> + <sender>buttonOk</sender> + <signal>clicked()</signal> + <receiver>HostDialogBase</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>buttonCancel</sender> + <signal>clicked()</signal> + <receiver>HostDialogBase</receiver> + <slot>reject()</slot> + </connection> + <connection> + <sender>snmpVersion</sender> + <signal>activated(const QString&)</signal> + <receiver>HostDialogBase</receiver> + <slot>showSnmpAuthenticationDetailsForVersion(const QString&)</slot> + </connection> + <connection> + <sender>securityLevel</sender> + <signal>activated(const QString&)</signal> + <receiver>HostDialogBase</receiver> + <slot>enableDisabledAuthenticationAndPrivacyElementsForSecurityLevel(const QString&)</slot> + </connection> + <connection> + <sender>hostName</sender> + <signal>textChanged(const QString&)</signal> + <receiver>HostDialogBase</receiver> + <slot>checkValidity()</slot> + </connection> + <connection> + <sender>securityName</sender> + <signal>textChanged(const QString&)</signal> + <receiver>HostDialogBase</receiver> + <slot>checkValidity()</slot> + </connection> + <connection> + <sender>communityString</sender> + <signal>textChanged(const QString&)</signal> + <receiver>HostDialogBase</receiver> + <slot>checkValidity()</slot> + </connection> + <connection> + <sender>testHostButton</sender> + <signal>clicked()</signal> + <receiver>HostDialogBase</receiver> + <slot>testHost()</slot> + </connection> +</connections> +<tabstops> + <tabstop>hostName</tabstop> + <tabstop>port</tabstop> + <tabstop>snmpVersion</tabstop> + <tabstop>securityName</tabstop> + <tabstop>securityLevel</tabstop> + <tabstop>authenticationType</tabstop> + <tabstop>authenticationPassphrase</tabstop> + <tabstop>privacyType</tabstop> + <tabstop>privacyPassphrase</tabstop> + <tabstop>buttonOk</tabstop> + <tabstop>buttonCancel</tabstop> + <tabstop>communityString</tabstop> +</tabstops> +<slots> + <slot access="private">showSnmpAuthenticationDetailsForVersion(const QString &)</slot> + <slot>enableDisabledAuthenticationAndPrivacyElementsForSecurityLevel(const QString &)</slot> + <slot>checkValidity()</slot> + <slot access="protected">testHost()</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>kdialog.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>klineedit.h</includehint> +</includehints> +</UI> diff --git a/ksim/monitors/snmp/identifier.cpp b/ksim/monitors/snmp/identifier.cpp new file mode 100644 index 0000000..25c188e --- /dev/null +++ b/ksim/monitors/snmp/identifier.cpp @@ -0,0 +1,129 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + 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; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "identifier.h" +#include "snmp_p.h" +#include "snmplib.h" + +#include <assert.h> + +using namespace KSim::Snmp; + +Identifier::Data::Data( const oid *d, size_t length ) +{ + memcpy( data, d, length * sizeof( oid ) ); + this->length = length; +} + +Identifier::Identifier() + : d( new Data ) +{ +} + +Identifier::Identifier( Data *data ) + : d( data ) +{ + assert( d ); +} + +Identifier::Identifier( const Identifier &rhs ) + : d( new Data( *rhs.d ) ) +{ +} + +Identifier &Identifier::operator=( const Identifier &rhs ) +{ + if ( d == rhs.d ) + return *this; + + *d = *rhs.d; + + return *this; +} + +Identifier::~Identifier() +{ + delete d; +} + +Identifier Identifier::fromString( const QString &name, bool *ok ) +{ + Identifier res; + res.d->length = MAX_OID_LEN; + // if ( !get_node( name.ascii(), res.d->data, &res.d->length ) ) { + if ( name.isEmpty() || !SnmpLib::self()->snmp_parse_oid( name.ascii(), res.d->data, &res.d->length ) ) { + if ( ok ) + *ok = false; + return Identifier(); + } + + if ( ok ) + *ok = true; + + return res; +} + +QString Identifier::toString( PrintFlags flags ) const +{ + size_t buflen = 256; + size_t outlen = 0; + int overflow = 0; + + u_char *buf = ( u_char* )calloc( buflen, 1 ); + if ( !buf ) + return QString::null; + + int oldOutpuFormat = SnmpLib::self()->netsnmp_ds_get_int( NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT ); + SnmpLib::self()->netsnmp_ds_set_int( NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, + flags == PrintAscii ? NETSNMP_OID_OUTPUT_MODULE : NETSNMP_OID_OUTPUT_NUMERIC ); + + SnmpLib::self()->netsnmp_sprint_realloc_objid_tree( &buf, &buflen, &outlen, 1 /* alloc realloc */, + &overflow, d->data, d->length ); + + SnmpLib::self()->netsnmp_ds_set_int( NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, oldOutpuFormat ); + + if ( overflow ) { + free( buf ); + return QString::null; + } + + QString result = QString::fromAscii( ( char* )buf ); + + free( buf ); + + return result; +} + +bool Identifier::operator==( const Identifier &rhs ) const +{ + return SnmpLib::self()->netsnmp_oid_equals( d->data, d->length, rhs.d->data, rhs.d->length ) == 0; +} + +bool Identifier::operator<( const Identifier &rhs ) const +{ + return SnmpLib::self()->snmp_oid_compare( d->data, d->length, rhs.d->data, rhs.d->length ) < 0; +} + +bool Identifier::isNull() const +{ + return d->length == 0; +} + +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/identifier.h b/ksim/monitors/snmp/identifier.h new file mode 100644 index 0000000..7da54dd --- /dev/null +++ b/ksim/monitors/snmp/identifier.h @@ -0,0 +1,72 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + 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; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef IDENTIFIER_H +#define IDENTIFIER_H + +#include <qstring.h> +#include <qvaluelist.h> +#include <qmap.h> + +#include "value.h" + +namespace KSim +{ + +namespace Snmp +{ + +class Identifier +{ +public: + friend class PDU; + struct Data; + + enum PrintFlags { PrintAscii, PrintNumeric }; + + Identifier(); + Identifier( Data *data ); + Identifier( const Identifier &rhs ); + Identifier &operator=( const Identifier &rhs ); + ~Identifier(); + + static Identifier fromString( const QString &name, bool *ok = 0 ); + + QString toString( PrintFlags flags = PrintAscii ) const; + + bool isNull() const; + + bool operator==( const Identifier &rhs ) const; + bool operator!=( const Identifier &rhs ) const + { return !operator==( rhs ); } + bool operator<( const Identifier &rhs ) const; + +private: + Data *d; +}; + +typedef QValueList<Identifier> IdentifierList; +typedef QMap<Identifier, Value> ValueMap; + +} +} + +#endif // IDENTIFIER_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/labelmonitor.cpp b/ksim/monitors/snmp/labelmonitor.cpp new file mode 100644 index 0000000..24e48c7 --- /dev/null +++ b/ksim/monitors/snmp/labelmonitor.cpp @@ -0,0 +1,45 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + 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; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "labelmonitor.h" + +using namespace KSim::Snmp; + +LabelMonitor::LabelMonitor( const MonitorConfig &config, QWidget *parent, const char *name ) + : KSim::Label( parent, name ), m_config( config ) +{ +} + +void LabelMonitor::setData( const Value &data ) +{ + QString dataString = data.toString( m_config.refreshInterval.minutes == 0 ? Value::TimeTicksWithSeconds : 0 ); + + if ( m_config.useCustomFormatString ) { + QString text = m_config.customFormatString; + text.replace( "%n", m_config.name ); + text.replace( "%s", dataString ); + setText( text ); + } else + setText( m_config.name + ": " + dataString ); +} + +#include "labelmonitor.moc" + +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/labelmonitor.h b/ksim/monitors/snmp/labelmonitor.h new file mode 100644 index 0000000..3e92c69 --- /dev/null +++ b/ksim/monitors/snmp/labelmonitor.h @@ -0,0 +1,52 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + 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; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef LABELMONITOR_H +#define LABELMONITOR_H + +#include "label.h" +#include "value.h" +#include "monitorconfig.h" + +namespace KSim +{ + +namespace Snmp +{ + +class LabelMonitor : public KSim::Label +{ + Q_OBJECT +public: + LabelMonitor( const MonitorConfig &config, QWidget *parent, const char *name = 0 ); + +public slots: + void setData( const Value &data ); + +private: + MonitorConfig m_config; +}; + +} + +} + +#endif // LABELMONITOR_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/monitor.cpp b/ksim/monitors/snmp/monitor.cpp new file mode 100644 index 0000000..7a97825 --- /dev/null +++ b/ksim/monitors/snmp/monitor.cpp @@ -0,0 +1,96 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + 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; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "monitor.h" + +#include <qtimer.h> +#include <qapplication.h> + +using namespace KSim::Snmp; + +Monitor::Monitor( const HostConfig &host, const Identifier &oid, int refresh, QObject *parent, const char *name ) + : QObject( parent, name ), m_oid( oid ), m_session( host ) +{ + if ( refresh > 0 ) + m_timerId = startTimer( refresh ); + else + m_timerId = -1; + + QTimer::singleShot( 0, this, SLOT( performSnmpRequest() ) ); +} + +Monitor::~Monitor() +{ + if ( QThread::running() ) + QThread::wait(); +} + +void Monitor::run() +{ + AsyncSnmpQueryResult *result = new AsyncSnmpQueryResult; + + result->oid = m_oid; + result->success = performSyncSnmpRequest( result->data, &result->error ); + + QCustomEvent *ev = new QCustomEvent( QEvent::User, result ); + QApplication::postEvent( this, ev ); +} + +void Monitor::customEvent( QCustomEvent *ev ) +{ + if ( ev->type() != QEvent::User ) + return; + + AsyncSnmpQueryResult *result = reinterpret_cast<AsyncSnmpQueryResult *>( ev->data() ); + if ( result->success ) { + emit newData( result->data ); + emit newData( result->oid, result->data ); + } else { + emit error( result->error ); + emit error( result->oid, result->error ); + } + + delete result; +} + +void Monitor::timerEvent( QTimerEvent *ev ) +{ + if ( ev->timerId() != m_timerId ) + return; + + performSnmpRequest(); +} + +void Monitor::performSnmpRequest() +{ + if ( QThread::running() ) + return; + + start(); +} + +bool Monitor::performSyncSnmpRequest( Value &data, ErrorInfo *errorInfo ) +{ + return m_session.snmpGet( m_oid, data, errorInfo ); +} + +#include "monitor.moc" + +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/monitor.h b/ksim/monitors/snmp/monitor.h new file mode 100644 index 0000000..cd3dedc --- /dev/null +++ b/ksim/monitors/snmp/monitor.h @@ -0,0 +1,77 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + 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; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef MONITOR_H +#define MONITOR_H + +#include "monitorconfig.h" +#include "session.h" + +#include <qthread.h> + +namespace KSim +{ + +namespace Snmp +{ + +class Monitor : public QObject, public QThread +{ + Q_OBJECT +public: + Monitor( const HostConfig &host, const Identifier &oid, int refresh, QObject *parent = 0, const char *name = 0 ); + virtual ~Monitor(); + +signals: + void newData( const Value &data ); + void newData( const Identifier &oid, const Value &data ); + void error( const ErrorInfo &errorInfo ); + void error( const Identifier &oid, const ErrorInfo &errorInfo ); + +protected: + virtual void run(); + virtual void customEvent( QCustomEvent *ev ); + virtual void timerEvent( QTimerEvent *ev ); + +private slots: + void performSnmpRequest(); + bool performSyncSnmpRequest( Value &data, ErrorInfo *errorInfo = 0 ); + +private: + struct AsyncSnmpQueryResult + { + AsyncSnmpQueryResult() : success( false ) {} + Identifier oid; + Value data; + ErrorInfo error; + bool success; + }; + + const Identifier m_oid; + int m_timerId; + Session m_session; +}; + +} + +} + +#endif // MONITOR_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/monitorconfig.cpp b/ksim/monitors/snmp/monitorconfig.cpp new file mode 100644 index 0000000..6b3b27e --- /dev/null +++ b/ksim/monitors/snmp/monitorconfig.cpp @@ -0,0 +1,183 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + 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; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "monitorconfig.h" +#include "labelmonitor.h" +#include "chartmonitor.h" + +#include <assert.h> + +using namespace KSim::Snmp; + +MonitorConfig::MonitorConfig() +{ + display = Label; + refreshInterval.minutes = refreshInterval.seconds = 0; + useCustomFormatString = false; + displayCurrentValueInline = false; +} + +bool MonitorConfig::load( KConfigBase &config, const HostConfigMap &hosts ) +{ + QString hostName = config.readEntry( "Host" ); + if ( hostName.isEmpty() ) + return false; + + HostConfigMap::ConstIterator hostIt = hosts.find( hostName ); + if ( hostIt == hosts.end() ) + return false; + + host = *hostIt; + + name = config.readEntry( "MonitorName" ); + if ( name.isEmpty() ) + return false; + + oid = config.readEntry( "ObjectIdentifier" ); + if ( Identifier::fromString( oid ).isNull() ) + return false; + + bool ok = false; + display = stringToMonitorDisplayType( config.readEntry( "DisplayType" ), &ok ); + if ( !ok ) + return false; + + refreshInterval.minutes = config.readUnsignedNumEntry( "RefreshIntervalMinutes" ); + refreshInterval.seconds = config.readUnsignedNumEntry( "RefreshIntervalSeconds" ); + + if ( refreshInterval.minutes == 0 && refreshInterval.seconds == 0 ) + return false; + + if ( display == Label ) { + useCustomFormatString = config.readBoolEntry( "UseCustomFormatString", useCustomFormatString ); + if ( useCustomFormatString ) + customFormatString = config.readEntry( "CustomFormatString" ); + } else + displayCurrentValueInline = config.readBoolEntry( "DisplayCurrentValueInline", displayCurrentValueInline ); + + return true; +} + +void MonitorConfig::save( KConfigBase &config ) const +{ + if ( isNull() ) + return; + + config.writeEntry( "Host", host.name ); + config.writeEntry( "MonitorName", name ); + config.writeEntry( "ObjectIdentifier", oid ); + config.writeEntry( "DisplayType", monitorDisplayTypeToString( display ) ); + config.writeEntry( "RefreshIntervalMinutes", refreshInterval.minutes ); + config.writeEntry( "RefreshIntervalSeconds", refreshInterval.seconds ); + if ( display == Label ) { + config.writeEntry( "UseCustomFormatString", useCustomFormatString ); + if ( useCustomFormatString ) + config.writeEntry( "CustomFormatString", customFormatString ); + } else + config.writeEntry( "DisplayCurrentValueInline", displayCurrentValueInline ); +} + +QWidget *MonitorConfig::createMonitorWidget( QWidget *parent, const char *name ) +{ + QWidget *w; + + int refresh = refreshInterval.seconds * 1000 + refreshInterval.minutes * 60 * 1000; + Identifier id = Identifier::fromString( oid ); + if ( id.isNull() ) + return 0; + + if ( display == Label ) + w = new LabelMonitor( *this, parent, name ); + else + w = new ChartMonitor( *this, parent, name ); + + Monitor *monitor = new Monitor( host, id, refresh, w ); + QObject::connect( monitor, SIGNAL( newData( const Value & ) ), + w, SLOT( setData( const Value & ) ) ); + return w; +} + +QString KSim::Snmp::monitorDisplayTypeToString( MonitorConfig::DisplayType type ) +{ + switch ( type ) + { + case MonitorConfig::Label: return QString::fromLatin1( "Label" ); + case MonitorConfig::Chart: return QString::fromLatin1( "Chart" ); + default: assert( false ); + }; + return QString::null; +} + +MonitorConfig::DisplayType KSim::Snmp::stringToMonitorDisplayType( QString string, bool *ok ) +{ + string = string.lower(); + if ( string == "chart" ) { + if ( ok ) + *ok = true; + return MonitorConfig::Chart; + } + if ( string == "label" ) { + if ( ok ) + *ok = true; + return MonitorConfig::Label; + } + if ( ok ) + *ok = false; + return MonitorConfig::Chart; +} + +QStringList KSim::Snmp::allDisplayTypes() +{ + // !!! keep order with enum + return QStringList() << "Label" << "Chart"; +} + +void MonitorConfigMap::load( KConfigBase &config, const QStringList &names, const HostConfigMap &hosts ) +{ + clear(); + + for ( QStringList::ConstIterator it = names.begin(); it != names.end(); ++it ) { + config.setGroup( "Monitor " + *it ); + + MonitorConfig monitor; + if ( !monitor.load( config, hosts ) ) + continue; + + insert( *it, monitor ); + } +} + +QStringList MonitorConfigMap::save( KConfigBase &config ) const +{ + QStringList names; + + for ( ConstIterator it = begin(); it != end(); ++it ) { + QString name = it.key(); + + names << name; + + config.setGroup( "Monitor " + name ); + ( *it ).save( config ); + } + + return names; +} + +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/monitorconfig.h b/ksim/monitors/snmp/monitorconfig.h new file mode 100644 index 0000000..bbc8674 --- /dev/null +++ b/ksim/monitors/snmp/monitorconfig.h @@ -0,0 +1,84 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + 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; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef MONITORCONFIG_H +#define MONITORCONFIG_H + +#include "hostconfig.h" + +namespace KSim +{ + +namespace Snmp +{ + +struct MonitorConfig +{ + enum DisplayType { Label = 0, Chart }; + + MonitorConfig(); + MonitorConfig( KConfigBase &config, const HostConfigMap &hosts ) + { load( config, hosts ); } + + bool load( KConfigBase &config, const HostConfigMap &hosts ); + void save( KConfigBase &config ) const; + + bool isNull() const { return name.isEmpty() || host.isNull(); } + + QWidget *createMonitorWidget( QWidget *parent, const char *name = 0 ); + + HostConfig host; + QString name; + QString oid; + struct + { + uint minutes; + uint seconds; + } refreshInterval; + DisplayType display; + + bool useCustomFormatString; + QString customFormatString; + + bool displayCurrentValueInline; +}; + +struct MonitorConfigMap : public QMap< QString, MonitorConfig > +{ + MonitorConfigMap() {} + MonitorConfigMap( const QMap< QString, MonitorConfig > &rhs ) + : QMap< QString, MonitorConfig >( rhs ) {} + + void load( KConfigBase &config, const QStringList &names, const HostConfigMap &hosts ); + QStringList save( KConfigBase &config ) const; +}; + +typedef QValueList<MonitorConfig> MonitorConfigList; + +QString monitorDisplayTypeToString( MonitorConfig::DisplayType type ); +MonitorConfig::DisplayType stringToMonitorDisplayType( QString string, bool *ok = 0 ); +QStringList allDisplayTypes(); + +} + +} + +#endif // MONITORCONFIG_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/monitordialog.cpp b/ksim/monitors/snmp/monitordialog.cpp new file mode 100644 index 0000000..615a1aa --- /dev/null +++ b/ksim/monitors/snmp/monitordialog.cpp @@ -0,0 +1,178 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + 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; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "monitordialog.h" +#include "identifier.h" +#include "browsedialog.h" + +#include <qcombobox.h> +#include <qlineedit.h> +#include <qspinbox.h> +#include <qpushbutton.h> +#include <qradiobutton.h> +#include <qbuttongroup.h> +#include <qcheckbox.h> +#include <qlabel.h> + +#include <klocale.h> +#include <kpushbutton.h> + +#include <assert.h> + +using namespace KSim::Snmp; + +MonitorDialog::MonitorDialog( const HostConfigMap &hosts, QWidget *parent, const char *name ) + : MonitorDialogBase( parent, name ), m_hosts( hosts ) +{ + init(); +} + +MonitorDialog::MonitorDialog( const MonitorConfig &monitor, const HostConfigMap &hosts, QWidget *parent, const char *name ) + : MonitorDialogBase( parent, name ), m_hosts( hosts ) +{ + init( monitor ); +} + +MonitorConfig MonitorDialog::monitorConfig() const +{ + MonitorConfig result; + + result.host = currentHost(); + if ( result.host.isNull() ) + return MonitorConfig(); + + result.name = monitorName->text(); + if ( result.name.isEmpty() ) + return MonitorConfig(); + + result.oid = oid->text(); + if ( Identifier::fromString( result.oid ).isNull() ) + return MonitorConfig(); + + result.refreshInterval.minutes = updateIntervalMinutes->value(); + result.refreshInterval.seconds = updateIntervalSeconds->value(); + + result.display = stringToMonitorDisplayType( displayType->currentText() ); + + if ( result.display == MonitorConfig::Label ) { + result.useCustomFormatString = customFormatStringCheckBox->isChecked(); + if ( result.useCustomFormatString ) + result.customFormatString = customFormatString->text(); + } else + result.displayCurrentValueInline = displayCurrentValueInline->isChecked(); + + return result; +} + +void MonitorDialog::checkValues() +{ + bool currentDisplayTypeIsLabel = stringToMonitorDisplayType( displayType->currentText() ) == MonitorConfig::Label; + labelOptions->setEnabled( currentDisplayTypeIsLabel ); + chartOptions->setEnabled( !currentDisplayTypeIsLabel ); + + QString statusText; + + if ( monitorName->text().isEmpty() ) + statusText = i18n( "Please enter a name for this monitor" ); + + if ( statusText.isEmpty() && Identifier::fromString( oid->text() ).isNull() ) + statusText = i18n( "Please enter a valid name for the object identifier" ); + + if ( statusText.isEmpty() ) + statusText = " "; // a space to keep the height + + status->setText( statusText ); + + buttonOk->setEnabled( !monitorConfig().isNull() ); +} + +void MonitorDialog::testObject() +{ + // ### FIXME +} + +void MonitorDialog::browse() +{ + HostConfig host = currentHost(); + if ( host.isNull() ) + return; + + BrowseDialog dlg( host, oid->text(), this ); + if ( dlg.exec() ) + oid->setText( dlg.selectedObjectIdentifier() ); +} + +void MonitorDialog::init( const MonitorConfig &monitor ) +{ + customFormatString->setText( "%s" ); + + status->setText( " " ); + + host->clear(); + + QStringList allHosts; + for ( HostConfigMap::ConstIterator it = m_hosts.begin(); it != m_hosts.end(); ++it ) + allHosts << it.key(); + + host->insertStringList( allHosts ); + + displayType->clear(); + displayType->insertStringList( allDisplayTypes() ); + + if ( monitor.isNull() ) { + checkValues(); + return; + } + + monitorName->setText( monitor.name ); + + assert( allHosts.findIndex( monitor.host.name ) != -1 ); + + host->setCurrentItem( allHosts.findIndex( monitor.host.name ) ); + + oid->setText( monitor.oid ); + + updateIntervalMinutes->setValue( monitor.refreshInterval.minutes ); + updateIntervalSeconds->setValue( monitor.refreshInterval.seconds ); + + displayType->setCurrentItem( allDisplayTypes().findIndex( monitorDisplayTypeToString( monitor.display ) ) ); + + customFormatStringCheckBox->setChecked( monitor.useCustomFormatString ); + customFormatString->setEnabled( monitor.useCustomFormatString ); + + if ( monitor.useCustomFormatString ) + customFormatString->setText( monitor.customFormatString ); + + displayCurrentValueInline->setChecked( monitor.displayCurrentValueInline ); + + checkValues(); +} + +HostConfig MonitorDialog::currentHost() const +{ + HostConfigMap::ConstIterator hostIt = m_hosts.find( host->currentText() ); + if ( hostIt == m_hosts.end() ) + return HostConfig(); + + return *hostIt; +} + +#include "monitordialog.moc" +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/monitordialog.h b/ksim/monitors/snmp/monitordialog.h new file mode 100644 index 0000000..0f22d33 --- /dev/null +++ b/ksim/monitors/snmp/monitordialog.h @@ -0,0 +1,60 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + 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; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef MONITORDIALOG_H +#define MONITORDIALOG_H + +#include "monitordialogbase.h" +#include "monitorconfig.h" + +namespace KSim +{ + +namespace Snmp +{ + +class MonitorDialog : public MonitorDialogBase +{ + Q_OBJECT +public: + MonitorDialog( const HostConfigMap &hosts, QWidget *parent, const char *name = 0 ); + MonitorDialog( const MonitorConfig &monitor, const HostConfigMap &hosts, QWidget *parent, const char *name = 0 ); + + MonitorConfig monitorConfig() const; + +protected: + virtual void checkValues(); + virtual void testObject(); + virtual void browse(); + +private: + void init( const MonitorConfig &monitor = MonitorConfig() ); + + HostConfig currentHost() const; + + HostConfigMap m_hosts; +}; + +} + +} + +#endif // MONITORDIALOG_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/monitordialogbase.ui b/ksim/monitors/snmp/monitordialogbase.ui new file mode 100644 index 0000000..13d6b06 --- /dev/null +++ b/ksim/monitors/snmp/monitordialogbase.ui @@ -0,0 +1,440 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>KSim::Snmp::MonitorDialogBase</class> +<widget class="KDialog"> + <property name="name"> + <cstring>MonitorDialogBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>725</width> + <height>597</height> + </rect> + </property> + <property name="caption"> + <string>Configure Monitor</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="4" column="0"> + <property name="name"> + <cstring>textLabel5</cstring> + </property> + <property name="text"> + <string>Display type:</string> + </property> + </widget> + <widget class="QLabel" row="3" column="0"> + <property name="name"> + <cstring>textLabel2</cstring> + </property> + <property name="text"> + <string>Update interval:</string> + </property> + </widget> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>Object identifier:</string> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel1_2</cstring> + </property> + <property name="text"> + <string>Name:</string> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>textLabel1_3</cstring> + </property> + <property name="text"> + <string>Host:</string> + </property> + </widget> + <widget class="QGroupBox" row="5" column="0" rowspan="1" colspan="4"> + <property name="name"> + <cstring>labelOptions</cstring> + </property> + <property name="title"> + <string>Options for Label</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QCheckBox" row="0" column="0"> + <property name="name"> + <cstring>customFormatStringCheckBox</cstring> + </property> + <property name="text"> + <string>Use custom format string:</string> + </property> + </widget> + <widget class="QLineEdit" row="0" column="1"> + <property name="name"> + <cstring>customFormatString</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + </widget> + <widget class="QLabel" row="1" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>textLabel1_4</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>The text in the edit box is what is displayed except that any occurrence of <b>%s</b> will be replaced with the snmp object value and any occurrence of <b>%n</b> will be replaced with the name of this monitor (see Name input field) .</string> + </property> + <property name="alignment"> + <set>WordBreak|AlignVCenter</set> + </property> + </widget> + </grid> + </widget> + <widget class="QLayoutWidget" row="3" column="1" rowspan="1" colspan="3"> + <property name="name"> + <cstring>layout2</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QSpinBox"> + <property name="name"> + <cstring>updateIntervalMinutes</cstring> + </property> + <property name="maxValue"> + <number>60</number> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel4</cstring> + </property> + <property name="text"> + <string>minutes</string> + </property> + </widget> + <widget class="QSpinBox"> + <property name="name"> + <cstring>updateIntervalSeconds</cstring> + </property> + <property name="maxValue"> + <number>59</number> + </property> + <property name="minValue"> + <number>1</number> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel3</cstring> + </property> + <property name="text"> + <string>seconds</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>141</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + <widget class="QLayoutWidget" row="4" column="1" rowspan="1" colspan="3"> + <property name="name"> + <cstring>layout3</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QComboBox"> + <item> + <property name="text"> + <string>Chart</string> + </property> + </item> + <item> + <property name="text"> + <string>Text Label</string> + </property> + </item> + <property name="name"> + <cstring>displayType</cstring> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer3</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>271</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + <spacer row="0" column="2" rowspan="1" colspan="2"> + <property name="name"> + <cstring>spacer4</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>244</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QLineEdit" row="0" column="1"> + <property name="name"> + <cstring>monitorName</cstring> + </property> + </widget> + <spacer row="1" column="2" rowspan="1" colspan="2"> + <property name="name"> + <cstring>spacer5</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>210</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QComboBox" row="1" column="1"> + <property name="name"> + <cstring>host</cstring> + </property> + </widget> + <widget class="QLayoutWidget" row="9" column="0" rowspan="1" colspan="4"> + <property name="name"> + <cstring>Layout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <spacer> + <property name="name"> + <cstring>Horizontal Spacing2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonOk</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonCancel</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + </widget> + </hbox> + </widget> + <widget class="Line" row="8" column="0" rowspan="1" colspan="4"> + <property name="name"> + <cstring>line1</cstring> + </property> + <property name="frameShape"> + <enum>HLine</enum> + </property> + <property name="frameShadow"> + <enum>Sunken</enum> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + </widget> + <widget class="QLabel" row="7" column="0" rowspan="1" colspan="4"> + <property name="name"> + <cstring>status</cstring> + </property> + <property name="text"> + <string>blehStatus</string> + </property> + </widget> + <widget class="QGroupBox" row="6" column="0" rowspan="1" colspan="4"> + <property name="name"> + <cstring>chartOptions</cstring> + </property> + <property name="title"> + <string>Options for Chart</string> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QCheckBox"> + <property name="name"> + <cstring>displayCurrentValueInline</cstring> + </property> + <property name="text"> + <string>Treat data as byte transfer rate and display the current value inline</string> + </property> + </widget> + </hbox> + </widget> + <widget class="KPushButton" row="2" column="3"> + <property name="name"> + <cstring>browseButton</cstring> + </property> + <property name="text"> + <string>Browse...</string> + </property> + </widget> + <widget class="QLineEdit" row="2" column="1" rowspan="1" colspan="2"> + <property name="name"> + <cstring>oid</cstring> + </property> + </widget> + </grid> +</widget> +<connections> + <connection> + <sender>buttonOk</sender> + <signal>clicked()</signal> + <receiver>MonitorDialogBase</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>buttonCancel</sender> + <signal>clicked()</signal> + <receiver>MonitorDialogBase</receiver> + <slot>reject()</slot> + </connection> + <connection> + <sender>monitorName</sender> + <signal>textChanged(const QString&)</signal> + <receiver>MonitorDialogBase</receiver> + <slot>checkValues()</slot> + </connection> + <connection> + <sender>oid</sender> + <signal>textChanged(const QString&)</signal> + <receiver>MonitorDialogBase</receiver> + <slot>checkValues()</slot> + </connection> + <connection> + <sender>displayType</sender> + <signal>activated(const QString&)</signal> + <receiver>MonitorDialogBase</receiver> + <slot>checkValues()</slot> + </connection> + <connection> + <sender>customFormatStringCheckBox</sender> + <signal>toggled(bool)</signal> + <receiver>customFormatString</receiver> + <slot>setEnabled(bool)</slot> + </connection> + <connection> + <sender>browseButton</sender> + <signal>clicked()</signal> + <receiver>MonitorDialogBase</receiver> + <slot>browse()</slot> + </connection> +</connections> +<tabstops> + <tabstop>monitorName</tabstop> + <tabstop>host</tabstop> + <tabstop>oid</tabstop> + <tabstop>updateIntervalMinutes</tabstop> + <tabstop>updateIntervalSeconds</tabstop> + <tabstop>displayType</tabstop> + <tabstop>buttonOk</tabstop> + <tabstop>buttonCancel</tabstop> +</tabstops> +<slots> + <slot access="protected">checkValues()</slot> + <slot access="protected">browse()</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>kdialog.h</includehint> + <includehint>kpushbutton.h</includehint> +</includehints> +</UI> diff --git a/ksim/monitors/snmp/pdu.cpp b/ksim/monitors/snmp/pdu.cpp new file mode 100644 index 0000000..1619086 --- /dev/null +++ b/ksim/monitors/snmp/pdu.cpp @@ -0,0 +1,98 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + 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; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "pdu.h" +#include "snmp_p.h" +#include "value_p.h" + +#include <algorithm> +#include <functional> + +#include <assert.h> + +using namespace KSim::Snmp; + +PDU::PDU() + : d( 0 ) +{ +} + +PDU::PDU( int requestType ) +{ + d = SnmpLib::self()->snmp_pdu_create( requestType ); +} + +PDU::~PDU() +{ + if ( d ) + SnmpLib::self()->snmp_free_pdu( d ); +} + +void PDU::addNullVariables( const IdentifierList &oids ) +{ + std::for_each( oids.begin(), oids.end(), + std::bind1st( std::mem_fun( &PDU::addNullVariable ), this ) ); +} + +void PDU::addNullVariable( Identifier oid ) +{ + assert( d ); + SnmpLib::self()->snmp_add_null_var( d, oid.d->data, oid.d->length ); +} + +netsnmp_pdu *PDU::release() +{ + netsnmp_pdu *res = d; + d = 0; + return res; +} + +bool PDU::hasError() const +{ + if ( !d ) + return false; + + return d->errstat != SNMP_ERR_NOERROR; +} + +int PDU::errorCode() const +{ + return d->errstat; +} + +ValueMap PDU::variables() const +{ + if ( !d ) + return ValueMap(); + + ValueMap result; + + for ( variable_list *var = d->variables; var; var = var->next_variable ) { + Identifier oid( new Identifier::Data( var->name, var->name_length ) ); + Value value( new ValueImpl( var ) ); + + result.insert( oid, value ); + } + + return result; +} + +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/pdu.h b/ksim/monitors/snmp/pdu.h new file mode 100644 index 0000000..2e648d4 --- /dev/null +++ b/ksim/monitors/snmp/pdu.h @@ -0,0 +1,60 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + 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; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef PDU_H +#define PDU_H + +#include "identifier.h" +#include "snmplib.h" + +namespace KSim +{ + +namespace Snmp +{ + +class PDU +{ +public: + PDU(); + PDU( int requestType ); + ~PDU(); + + void addNullVariables( const IdentifierList &oids ); + void addNullVariable( Identifier oid ); + + netsnmp_pdu **operator&() { return &d; } + + netsnmp_pdu *release(); + + bool hasError() const; + int errorCode() const; + + ValueMap variables() const; + +private: + netsnmp_pdu *d; +}; + +} +} + +#endif // PDU_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/plugin.cpp b/ksim/monitors/snmp/plugin.cpp new file mode 100644 index 0000000..90683a2 --- /dev/null +++ b/ksim/monitors/snmp/plugin.cpp @@ -0,0 +1,52 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + 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; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "plugin.h" +#include "view.h" +#include "configpage.h" + +using namespace KSim::Snmp; + +KSIM_INIT_PLUGIN( Plugin ); + +Plugin::Plugin( const char *name ) + : KSim::PluginObject( name ) +{ +} + +Plugin::~Plugin() +{ +} + +KSim::PluginView *Plugin::createView( const char *name ) +{ + return new View( this, name ); +} + +KSim::PluginPage *Plugin::createConfigPage( const char *name ) +{ + return new ConfigPage( this, name ); +} + +void Plugin::showAbout() +{ +} + +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/plugin.h b/ksim/monitors/snmp/plugin.h new file mode 100644 index 0000000..3e0fb66 --- /dev/null +++ b/ksim/monitors/snmp/plugin.h @@ -0,0 +1,49 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + 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; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KSIM_PLUGIN_H +#define KSIM_PLUGIN_H + +#include <pluginmodule.h> + +namespace KSim +{ + +namespace Snmp +{ + +class Plugin : public KSim::PluginObject +{ +public: + Plugin( const char *name ); + ~Plugin(); + + virtual KSim::PluginView *createView( const char *name ); + virtual KSim::PluginPage *createConfigPage( const char *name ); + + virtual void showAbout(); +}; + +} + +} + +#endif // KSIM_PLUGIN_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/probedialog.cpp b/ksim/monitors/snmp/probedialog.cpp new file mode 100644 index 0000000..d45db6b --- /dev/null +++ b/ksim/monitors/snmp/probedialog.cpp @@ -0,0 +1,117 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + 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; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "probedialog.h" +#include "monitor.h" + +#include <qtimer.h> + +#include <klocale.h> +#include <kdebug.h> + +using namespace KSim::Snmp; + +static const char * const probeIdentifiers[] = +{ + "system.sysDescr.0", + "system.sysName.0", + "system.sysUpTime.0", + "system.sysContact.0", + "system.sysObjectID.0", + ".1.3.6.1.2.1.25.1.1.0", + 0 +}; + +ProbeDialog::ProbeDialog( const HostConfig &hostConfig, QWidget *parent, const char *name ) + : KProgressDialog( parent, name, i18n( "SNMP Host Probe" ), QString::null, true /* modal */ ), + m_host( hostConfig ), m_currentMonitor( 0 ), m_canceled( false ) +{ + setLabel( i18n( "Probing for common object identifiers..." ) ); + + for ( uint i = 0; probeIdentifiers[ i ]; ++i ) { + Identifier id = Identifier::fromString( probeIdentifiers[ i ] ); + if ( !id.isNull() ) + m_probeOIDs << id; + } + + progressBar()->setTotalSteps( m_probeOIDs.count() ); + + setAutoClose( false ); + + nextProbe(); +} + +void ProbeDialog::done( int code ) +{ + if ( code == QDialog::Rejected && m_currentMonitor ) { + setLabel( "Probe aborted. Waiting for job to finish..." ); + m_canceled = true; + return; + } + KProgressDialog::done( code ); +} + +void ProbeDialog::probeOne() +{ + if ( m_probeOIDs.isEmpty() ) { + accept(); + return; + } + + Identifier oid = m_probeOIDs.pop(); + + delete m_currentMonitor; + m_currentMonitor = new Monitor( m_host, oid, 0 /* no refresh */, this ); + + connect( m_currentMonitor, SIGNAL( newData( const Identifier &, const Value & ) ), + this, SLOT( probeResult( const Identifier &, const Value & ) ) ); + connect( m_currentMonitor, SIGNAL( error( const Identifier &, const ErrorInfo & ) ), + this, SLOT( probeError( const Identifier &, const ErrorInfo & ) ) ); +} + +void ProbeDialog::probeResult( const Identifier &oid, const Value &value ) +{ + if ( !m_canceled ) + m_results << ProbeResult( oid, value ); + + nextProbe(); +} + +void ProbeDialog::probeError( const Identifier &oid, const ErrorInfo &errorInfo ) +{ + if ( !m_canceled ) + m_results << ProbeResult( oid, errorInfo ); + + nextProbe(); +} + +void ProbeDialog::nextProbe() +{ + progressBar()->setProgress( progressBar()->totalSteps() - m_probeOIDs.count() ); + + if ( m_canceled ) + KProgressDialog::done( QDialog::Rejected ); + else + QTimer::singleShot( 0, this, SLOT( probeOne() ) ); +} + +#include "probedialog.moc" + +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/probedialog.h b/ksim/monitors/snmp/probedialog.h new file mode 100644 index 0000000..47a5fb0 --- /dev/null +++ b/ksim/monitors/snmp/probedialog.h @@ -0,0 +1,87 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + 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; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef PROBEDIALOG_H +#define PROBEDIALOG_H + +#include <qvaluestack.h> + +#include <kprogress.h> + +#include "hostconfig.h" +#include "identifier.h" + +namespace KSim +{ + +namespace Snmp +{ + +class Monitor; + +class ProbeDialog : public KProgressDialog +{ + Q_OBJECT +public: + ProbeDialog( const HostConfig &hostConfig, QWidget *parent, const char *name = 0 ); + + struct ProbeResult + { + ProbeResult() : success( false ) {} + ProbeResult( const Identifier &_oid, const Value &_value ) + : oid( _oid ), value( _value ), success( true ) + {} + ProbeResult( const Identifier &_oid, const ErrorInfo &_errorInfo ) + : oid( _oid ), success( false ), errorInfo( _errorInfo ) + {} + + Identifier oid; + Value value; + bool success; + ErrorInfo errorInfo; + }; + typedef QValueList<ProbeResult> ProbeResultList; + + ProbeResultList probeResults() const { return m_results; } + +protected: + virtual void done( int code ); + +private slots: + void probeOne(); + void probeResult( const Identifier &oid, const Value &value ); + void probeError( const Identifier &oid, const ErrorInfo &errorInfo ); + +private: + void nextProbe(); + + HostConfig m_host; + QValueStack<Identifier> m_probeOIDs; + Monitor *m_currentMonitor; + + ProbeResultList m_results; + bool m_canceled; +}; + +} +} + +#endif // PROBEDIALOG_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/proberesultdialog.cpp b/ksim/monitors/snmp/proberesultdialog.cpp new file mode 100644 index 0000000..641f12e --- /dev/null +++ b/ksim/monitors/snmp/proberesultdialog.cpp @@ -0,0 +1,55 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + 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; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "proberesultdialog.h" + +#include <qlabel.h> + +#include <klocale.h> +#include <klistview.h> + +using namespace KSim::Snmp; + +ProbeResultDialog::ProbeResultDialog( const HostConfig &hostConfig, const ProbeDialog::ProbeResultList &probeResults, + QWidget *parent, const char *name ) + : ProbeResultDialogBase( parent, name ) +{ + info->setText( i18n( "Results of scanning host %1:" ).arg( hostConfig.name ) ); + + for ( ProbeDialog::ProbeResultList::ConstIterator it = probeResults.begin(); + it != probeResults.end(); ++it ) + addResultItem( *it ); +} + +void ProbeResultDialog::addResultItem( const ProbeDialog::ProbeResult &result ) +{ + QListViewItem *item = new QListViewItem( probeResultView ); + + item->setText( 0, result.oid.toString() ); + + if ( result.success ) + item->setText( 1, result.value.toString( Value::TimeTicksWithSeconds ) ); + else + item->setText( 1, QString( "ERROR: " ) + result.errorInfo.errorMessage() ); +} + +#include "proberesultdialog.moc" + +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/proberesultdialog.h b/ksim/monitors/snmp/proberesultdialog.h new file mode 100644 index 0000000..9ba3523 --- /dev/null +++ b/ksim/monitors/snmp/proberesultdialog.h @@ -0,0 +1,49 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + 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; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef PROBERESULTDIALOG_H +#define PROBERESULTDIALOG_H + +#include "proberesultdialogbase.h" + +#include "probedialog.h" + +namespace KSim +{ + +namespace Snmp +{ + +class ProbeResultDialog : public ProbeResultDialogBase +{ + Q_OBJECT +public: + ProbeResultDialog( const HostConfig &hostConfig, const ProbeDialog::ProbeResultList &probeResults, + QWidget *parent, const char *name = 0 ); + +private: + void addResultItem( const ProbeDialog::ProbeResult &result ); +}; + +} + +} +#endif // PROBERESULTDIALOG_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/proberesultdialogbase.ui b/ksim/monitors/snmp/proberesultdialogbase.ui new file mode 100644 index 0000000..01b0c70 --- /dev/null +++ b/ksim/monitors/snmp/proberesultdialogbase.ui @@ -0,0 +1,124 @@ +<!DOCTYPE UI><UI version="3.2" stdsetdef="1"> +<class>KSim::Snmp::ProbeResultDialogBase</class> +<widget class="QDialog"> + <property name="name"> + <cstring>ProbeResultDialogBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>501</width> + <height>321</height> + </rect> + </property> + <property name="caption"> + <string>Probe Results</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>info</cstring> + </property> + <property name="text"> + <string></string> + </property> + </widget> + <widget class="KListView"> + <column> + <property name="text"> + <string>Object</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Value</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>probeResultView</cstring> + </property> + <property name="allColumnsShowFocus"> + <bool>true</bool> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <spacer> + <property name="name"> + <cstring>Horizontal Spacing2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonOk</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + </hbox> + </widget> + </vbox> +</widget> +<connections> + <connection> + <sender>buttonOk</sender> + <signal>clicked()</signal> + <receiver>ProbeResultDialogBase</receiver> + <slot>accept()</slot> + </connection> +</connections> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>klistview.h</includehint> +</includehints> +</UI> diff --git a/ksim/monitors/snmp/session.cpp b/ksim/monitors/snmp/session.cpp new file mode 100644 index 0000000..d7de283 --- /dev/null +++ b/ksim/monitors/snmp/session.cpp @@ -0,0 +1,283 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + 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; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "session.h" +#include "snmp.h" +#include "snmp_p.h" +#include "snmplib.h" +#include "pdu.h" + +#include <assert.h> + +using namespace KSim::Snmp; + +// ### clean me up +struct Session::Data +{ + Data() : session( 0 ) {} + + netsnmp_session defaultSession; + netsnmp_session *session; + + bool initialized; + + HostConfig source; + + QCString host; + QCString community; + QCString securityName; + QCString authPassPhrase; + QCString privPassPhrase; +}; + +Session::Session( const HostConfig &source ) +{ + d = new Data; + d->initialized = false; + + d->source = source; + + // unicode madness + d->host = source.name.ascii(); + d->community = source.community.ascii(); + d->securityName = source.securityName.ascii(); + d->authPassPhrase = source.authentication.key.ascii(); + d->privPassPhrase = source.privacy.key.ascii(); + + SnmpLib::self()->snmp_sess_init( &d->defaultSession ); +} + +bool Session::snmpGetInternal( int getType, const IdentifierList &identifiers, ValueMap &variables, ErrorInfo *error ) +{ + if ( !d->initialized && !initialize( error ) ) + return false; + + bool result = false; + + if ( getType != SNMP_MSG_GETNEXT && d->session ) { + SnmpLib::self()->snmp_close( d->session ); + d->session = 0; + } + + if ( getType != SNMP_MSG_GETNEXT || + !d->session ) { + + if ( ( d->session = SnmpLib::self()->snmp_open( &d->defaultSession ) ) == 0 ) { + if ( error ) + *error = ErrorInfo( sessionErrorCode( d->defaultSession ) ); + return false; + } + } + + PDU request( getType ); + PDU response; + + request.addNullVariables( identifiers ); + + int status = SnmpLib::self()->snmp_synch_response( d->session, request.release(), &response ); + + if ( status == STAT_SUCCESS ) { + + if ( response.hasError() ) { + + if ( error ) + *error = ErrorInfo( response.errorCode() ); + + } else { + + variables = response.variables(); + result = true; + + if ( error ) + *error = ErrorInfo( ErrorInfo::NoError ); + } + + } else if ( status == STAT_TIMEOUT ) { + + if ( error ) + *error = ErrorInfo( ErrorInfo::ErrTimeout ); + + } else { + + if ( error ) + *error = ErrorInfo( sessionErrorCode( *d->session ) ); + + } + + if ( getType != SNMP_MSG_GETNEXT ) { + SnmpLib::self()->snmp_close( d->session ); + d->session = 0; + } + + return result; + +} + +bool Session::initialize( ErrorInfo *error ) +{ + if ( d->initialized ) { + if ( error ) + *error = ErrorInfo( ErrorInfo::NoError ); + return true; + } + + HostConfig &source = d->source; + + d->defaultSession.peername = d->host.data(); + + d->defaultSession.version = snmpVersionToSnmpLibConstant( source.version ); + + if ( source.version != SnmpVersion3 ) { + d->defaultSession.community = reinterpret_cast<u_char *>( d->community.data() ); + d->defaultSession.community_len = d->community.length(); + d->initialized = true; + return true; + } + + d->defaultSession.securityName = d->securityName.data(); + d->defaultSession.securityNameLen = d->securityName.length(); + + d->defaultSession.securityLevel = snmpSecurityLevelToSnmpLibConstant( source.securityLevel ); + + // ### clean me up + switch ( source.authentication.protocol ) { + case MD5Auth: { + d->defaultSession.securityAuthProto = usmHMACMD5AuthProtocol; + d->defaultSession.securityAuthProtoLen = USM_AUTH_PROTO_MD5_LEN; + break; + } + case SHA1Auth: { + d->defaultSession.securityAuthProto = usmHMACSHA1AuthProtocol; + d->defaultSession.securityAuthProtoLen = USM_AUTH_PROTO_SHA_LEN; + break; + } + default: assert( false ); + } + + d->defaultSession.securityAuthKeyLen = USM_AUTH_KU_LEN; + + int result; + if ( ( result = SnmpLib::self()->generate_Ku( d->defaultSession.securityAuthProto, d->defaultSession.securityAuthProtoLen, + reinterpret_cast<uchar *>( d->authPassPhrase.data() ), d->authPassPhrase.length(), + d->defaultSession.securityAuthKey, &d->defaultSession.securityAuthKeyLen ) ) + != SNMPERR_SUCCESS ) { + + if ( error ) + *error = ErrorInfo( result ); + + return false; + } + + switch ( source.privacy.protocol ) { + case DESPrivacy: { + d->defaultSession.securityPrivProto = usmDESPrivProtocol; + d->defaultSession.securityPrivProtoLen = USM_PRIV_PROTO_DES_LEN; + break; + } + default: assert( false ); + } + + d->defaultSession.securityPrivKeyLen = USM_PRIV_KU_LEN; + + if ( ( result = SnmpLib::self()->generate_Ku( d->defaultSession.securityAuthProto, d->defaultSession.securityAuthProtoLen, + reinterpret_cast<u_char *>( d->privPassPhrase.data() ), d->privPassPhrase.length(), + d->defaultSession.securityPrivKey, &d->defaultSession.securityPrivKeyLen ) ) + != SNMPERR_SUCCESS ) { + + if ( error ) + *error = ErrorInfo( result ); + + + return false; + } + + d->initialized = true; + return true; +} + +bool Session::snmpGet( const QString &identifier, Value &value, ErrorInfo *error ) +{ + bool ok = false; + Identifier oid = Identifier::fromString( identifier, &ok ); + if ( !ok ) { + if ( error ) + *error = ErrorInfo( ErrorInfo::ErrUnknownOID ); + return false; + } + + return snmpGet( oid, value, error ); +} + +bool Session::snmpGet( const Identifier &identifier, Value &value, ErrorInfo *error ) +{ + ValueMap vars; + IdentifierList ids; + + ids << identifier; + + if ( !snmpGet( ids, vars, error ) ) + return false; + + ValueMap::ConstIterator it = vars.find( identifier ); + if ( it == vars.end() ) { + if ( error ) + *error = ErrorInfo( ErrorInfo::ErrMissingVariables ); + return false; + } + + value = it.data(); + + return true; +} + +bool Session::snmpGet( const IdentifierList &identifiers, ValueMap &variables, ErrorInfo *error ) +{ + return snmpGetInternal( SNMP_MSG_GET, identifiers, variables, error ); +} + +bool Session::snmpGetNext( Identifier &identifier, Value &value, ErrorInfo *error ) +{ + ValueMap vars; + IdentifierList ids; + + ids << identifier; + + if ( !snmpGetInternal( SNMP_MSG_GETNEXT, ids, vars, error ) ) + return false; + + assert( vars.count() == 1 ); + + ValueMap::ConstIterator it = vars.begin(); + identifier = it.key(); + value = it.data(); + + return true; + +} + +Session::~Session() +{ + if ( d->session ) + SnmpLib::self()->snmp_close( d->session ); + delete d; +} + +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/session.h b/ksim/monitors/snmp/session.h new file mode 100644 index 0000000..0d5cda3 --- /dev/null +++ b/ksim/monitors/snmp/session.h @@ -0,0 +1,64 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + 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; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef SESSION_H +#define SESSION_H + +#include "hostconfig.h" +#include "value.h" +#include "identifier.h" + +namespace KSim +{ + +namespace Snmp +{ + +class Session +{ +public: + struct Data; + + Session( const HostConfig &snmpHostConfig ); + ~Session(); + + bool snmpGet( const QString &identifier, Value &value, ErrorInfo *error = 0 ); + bool snmpGet( const Identifier &identifier, Value &value, ErrorInfo *error = 0 ); + bool snmpGet( const IdentifierList &identifiers, ValueMap &variables, ErrorInfo *error = 0 ); + + bool snmpGetNext( Identifier &identifier, Value &value, ErrorInfo *error = 0 ); + +private: + Data *d; + + bool snmpGetInternal( int getType, const IdentifierList &identifiers, ValueMap &variables, ErrorInfo *error = 0 ); + + bool initialize( ErrorInfo *error ); + + Session( const Session & ); + Session &operator=( const Session & ); +}; + +} + +} + +#endif // SESSION_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/snmp.cpp b/ksim/monitors/snmp/snmp.cpp new file mode 100644 index 0000000..80fb073 --- /dev/null +++ b/ksim/monitors/snmp/snmp.cpp @@ -0,0 +1,320 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + 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; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "snmp.h" +#include "snmp_p.h" +#include "snmplib.h" +#include "value_p.h" + +#include <qmutex.h> + +#include <assert.h> + +using namespace KSim::Snmp; + +static const struct EnumStringMapInfo +{ + const int enumValue; + const char *stringValue; + const char snmpLibConstant; +} snmpVersionStrings[ 4 ] = { + { SnmpVersion1, "1", SNMP_VERSION_1 }, + { SnmpVersion2c, "2c", SNMP_VERSION_2c }, + { SnmpVersion3, "3", SNMP_VERSION_3 }, + { 0, 0, 0 } +}, securityLevelStrings[ 4 ] = { + { NoAuthPriv, "NoAuthPriv", SNMP_SEC_LEVEL_NOAUTH }, + { AuthNoPriv, "AuthNoPriv", SNMP_SEC_LEVEL_AUTHNOPRIV }, + { AuthPriv, "AuthPriv", SNMP_SEC_LEVEL_AUTHPRIV }, + { 0, 0, 0 } +}, authenticationProtocolStrings[ 3 ] = { + { MD5Auth, "MD5", 0 }, + { SHA1Auth, "SHA1", 0 }, + { 0, 0, 0 } +}, privacyProtocolStrings[ 2 ] = { + { DESPrivacy, "DES", 0 }, + { 0, 0, 0 } +}; + +static QStringList allStrings( const EnumStringMapInfo *array ) +{ + QStringList result; + for ( uint i = 0; array[ i ].stringValue; ++i ) + result << QString::fromLatin1( array[ i ].stringValue ); + return result; +} + +static QString enumToString( const EnumStringMapInfo *array, int value ) +{ + for ( uint i = 0; array[ i ].stringValue; ++i ) + if ( array[ i ].enumValue == value ) + return QString::fromLatin1( array[ i ].stringValue ); + + assert( false ); + return QString::null; +} + +static int stringToEnum( const EnumStringMapInfo *array, QString string, bool *ok ) +{ + string = string.lower(); + uint i; + for ( i = 0; array[ i ].stringValue; ++i ) + if ( QString::fromLatin1( array[ i ].stringValue ).lower() == string ) { + if ( ok ) *ok = true; + return array[ i ].enumValue; + } + + if ( ok ) + *ok = false; + + // something.. + return array[ 0 ].enumValue; +} + +static int extractSnmpLibConstant( const EnumStringMapInfo *array, int enumValue ) +{ + for ( uint i = 0; array[ i ].stringValue; ++i ) + if ( array[ i ].enumValue == enumValue ) + return array[ i ].snmpLibConstant; + + assert( false ); + return 0; +} + +int KSim::Snmp::snmpVersionToSnmpLibConstant( SnmpVersion version ) +{ + return extractSnmpLibConstant( snmpVersionStrings, version ); +} + +int KSim::Snmp::snmpSecurityLevelToSnmpLibConstant( SecurityLevel secLevel ) +{ + return extractSnmpLibConstant( securityLevelStrings, secLevel ); +} + +QStringList KSim::Snmp::allSnmpVersions() +{ + return allStrings( snmpVersionStrings ); +} + +QString KSim::Snmp::snmpVersionToString( SnmpVersion version ) +{ + return enumToString( snmpVersionStrings, version ); +} + +SnmpVersion KSim::Snmp::stringToSnmpVersion( QString string, bool *ok ) +{ + return static_cast<SnmpVersion>( stringToEnum( snmpVersionStrings, string, ok ) ); +} + +QStringList KSim::Snmp::allSecurityLevels() +{ + return allStrings( securityLevelStrings ); +} + +QString KSim::Snmp::securityLevelToString( SecurityLevel level ) +{ + return enumToString( securityLevelStrings, level ); +} + +SecurityLevel KSim::Snmp::stringToSecurityLevel( QString string, bool *ok ) +{ + return static_cast<SecurityLevel>( stringToEnum( securityLevelStrings, string, ok ) ); +} + +QStringList KSim::Snmp::allAuthenticationProtocols() +{ + return allStrings( authenticationProtocolStrings ); +} + +QString KSim::Snmp::authenticationProtocolToString( AuthenticationProtocol proto ) +{ + return enumToString( authenticationProtocolStrings, proto ); +} + +AuthenticationProtocol KSim::Snmp::stringToAuthenticationProtocol( QString string, bool *ok ) +{ + return static_cast<AuthenticationProtocol>( stringToEnum( authenticationProtocolStrings, string, ok ) ); +} + +QStringList KSim::Snmp::allPrivacyProtocols() +{ + return allStrings( privacyProtocolStrings ); +} + +QString KSim::Snmp::privacyProtocolToString( PrivacyProtocol proto ) +{ + return enumToString( privacyProtocolStrings, proto ); +} + +PrivacyProtocol KSim::Snmp::stringToPrivacyProtocol( QString string, bool *ok ) +{ + return static_cast<PrivacyProtocol>( stringToEnum( privacyProtocolStrings, string, ok ) ); +} + +// I'm afraid of them changing the order in the error constants or the like, hence the +// slow list instead of a fast lookup table +static const struct ErrorMapInfo +{ + int errorCode; + ErrorInfo::ErrorType enumValue; +} errorMap[] = +{ + // API Errors + { SNMPERR_GENERR, ErrorInfo::ErrGeneric }, + { SNMPERR_BAD_LOCPORT, ErrorInfo::ErrInvalidLocalPort }, + { SNMPERR_BAD_ADDRESS, ErrorInfo::ErrUnknownHost }, + { SNMPERR_BAD_SESSION, ErrorInfo::ErrUnknownSession }, + { SNMPERR_TOO_LONG, ErrorInfo::ErrTooLong }, + { SNMPERR_NO_SOCKET, ErrorInfo::ErrNoSocket }, + { SNMPERR_V2_IN_V1, ErrorInfo::ErrCannotSendV2PDUOnV1Session }, + { SNMPERR_V1_IN_V2, ErrorInfo::ErrCannotSendV1PDUOnV2Session }, + { SNMPERR_BAD_REPEATERS, ErrorInfo::ErrBadValueForNonRepeaters }, + { SNMPERR_BAD_REPETITIONS, ErrorInfo::ErrBadValueForMaxRepetitions }, + { SNMPERR_BAD_ASN1_BUILD, ErrorInfo::ErrBuildingASN1Representation }, + { SNMPERR_BAD_SENDTO, ErrorInfo::ErrFailureInSendto }, + { SNMPERR_BAD_PARSE, ErrorInfo::ErrBadParseOfASN1Type }, + { SNMPERR_BAD_VERSION, ErrorInfo::ErrBadVersion }, + { SNMPERR_BAD_SRC_PARTY, ErrorInfo::ErrBadSourceParty }, + { SNMPERR_BAD_DST_PARTY, ErrorInfo::ErrBadDestinationParty }, + { SNMPERR_BAD_CONTEXT, ErrorInfo::ErrBadContext }, + { SNMPERR_BAD_COMMUNITY, ErrorInfo::ErrBadCommunity }, + { SNMPERR_NOAUTH_DESPRIV, ErrorInfo::ErrCannotSendNoAuthDesPriv }, + { SNMPERR_BAD_ACL, ErrorInfo::ErrBadACL }, + { SNMPERR_BAD_PARTY, ErrorInfo::ErrBadParty }, + { SNMPERR_ABORT, ErrorInfo::ErrSessionAbortFailure }, + { SNMPERR_UNKNOWN_PDU, ErrorInfo::ErrUnknownPDU }, + { SNMPERR_TIMEOUT, ErrorInfo::ErrTimeout }, + { SNMPERR_BAD_RECVFROM, ErrorInfo::ErrFailureInRecvfrom }, + { SNMPERR_BAD_ENG_ID, ErrorInfo::ErrUnableToDetermineContextEngineID }, + { SNMPERR_BAD_SEC_NAME, ErrorInfo::ErrNoSecurityName }, + { SNMPERR_BAD_SEC_LEVEL, ErrorInfo::ErrUnableToDetermineSecurityLevel }, + { SNMPERR_ASN_PARSE_ERR, ErrorInfo::ErrASN1ParseError }, + { SNMPERR_UNKNOWN_SEC_MODEL, ErrorInfo::ErrUnknownSecurityModel }, + { SNMPERR_INVALID_MSG, ErrorInfo::ErrInvalidMessage }, + { SNMPERR_UNKNOWN_ENG_ID, ErrorInfo::ErrUnknownEngineID }, + { SNMPERR_UNKNOWN_USER_NAME, ErrorInfo::ErrUnknownUserName }, + { SNMPERR_UNSUPPORTED_SEC_LEVEL, ErrorInfo::ErrUnsupportedSecurityLevel }, + { SNMPERR_AUTHENTICATION_FAILURE, ErrorInfo::ErrAuthenticationFailure }, + { SNMPERR_NOT_IN_TIME_WINDOW, ErrorInfo::ErrNotInTimeWindow }, + { SNMPERR_DECRYPTION_ERR, ErrorInfo::ErrDecryptionError }, + { SNMPERR_SC_GENERAL_FAILURE, ErrorInfo::ErrSCAPIGeneralFailure }, + { SNMPERR_SC_NOT_CONFIGURED, ErrorInfo::ErrSCAPISubSystemNotConfigured }, + { SNMPERR_KT_NOT_AVAILABLE, ErrorInfo::ErrNoKeyTools }, + { SNMPERR_UNKNOWN_REPORT, ErrorInfo::ErrUnknownReport }, + { SNMPERR_USM_GENERICERROR, ErrorInfo::ErrUSMGenericError }, + { SNMPERR_USM_UNKNOWNSECURITYNAME, ErrorInfo::ErrUSMUnknownSecurityName }, + { SNMPERR_USM_UNSUPPORTEDSECURITYLEVEL, ErrorInfo::ErrUSMUnsupportedSecurityLevel }, + { SNMPERR_USM_ENCRYPTIONERROR, ErrorInfo::ErrUSMEncryptionError }, + { SNMPERR_USM_AUTHENTICATIONFAILURE, ErrorInfo::ErrUSMAuthenticationFailure }, + { SNMPERR_USM_PARSEERROR, ErrorInfo::ErrUSMParseError }, + { SNMPERR_USM_UNKNOWNENGINEID, ErrorInfo::ErrUSMUnknownEngineID }, + { SNMPERR_USM_NOTINTIMEWINDOW, ErrorInfo::ErrUSMNotInTimeWindow }, + { SNMPERR_USM_DECRYPTIONERROR, ErrorInfo::ErrUSMDecryptionError }, + { SNMPERR_NOMIB, ErrorInfo::ErrMIBNotInitialized }, + { SNMPERR_RANGE, ErrorInfo::ErrValueOutOfRange }, + { SNMPERR_MAX_SUBID, ErrorInfo::ErrSubIdOutOfRange }, + { SNMPERR_BAD_SUBID, ErrorInfo::ErrBadSubIdInOID }, + { SNMPERR_LONG_OID, ErrorInfo::ErrOIDTooLong }, + { SNMPERR_BAD_NAME, ErrorInfo::ErrBadValueName }, + { SNMPERR_VALUE, ErrorInfo::ErrBadValueNotation }, + { SNMPERR_UNKNOWN_OBJID, ErrorInfo::ErrUnknownOID }, + { SNMPERR_NULL_PDU, ErrorInfo::ErrNullPDU }, + { SNMPERR_NO_VARS, ErrorInfo::ErrMissingVariables }, + { SNMPERR_VAR_TYPE, ErrorInfo::ErrBadVariableType }, + { SNMPERR_MALLOC, ErrorInfo::ErrOOM }, + { SNMPERR_KRB5, ErrorInfo::ErrKerberos }, + + // PDU response errors + { SNMP_ERR_TOOBIG, ErrorInfo::ErrResponseTooLarge }, + { SNMP_ERR_NOSUCHNAME, ErrorInfo::ErrNoSuchVariable }, + { SNMP_ERR_BADVALUE, ErrorInfo::ErrBadValue }, + { SNMP_ERR_READONLY, ErrorInfo::ErrReadOnly }, + { SNMP_ERR_GENERR, ErrorInfo::ErrGeneric }, + { SNMP_ERR_NOACCESS, ErrorInfo::ErrNoAccess }, + { SNMP_ERR_WRONGTYPE, ErrorInfo::ErrWrongType }, + { SNMP_ERR_WRONGLENGTH, ErrorInfo::ErrWrongLength }, + { SNMP_ERR_WRONGENCODING, ErrorInfo::ErrWrongEncoding }, + { SNMP_ERR_WRONGVALUE, ErrorInfo::ErrWrongValue }, + { SNMP_ERR_NOCREATION, ErrorInfo::ErrNoCreation }, + { SNMP_ERR_INCONSISTENTVALUE, ErrorInfo::ErrInconsistentValue }, + { SNMP_ERR_RESOURCEUNAVAILABLE, ErrorInfo::ErrResourceUnavailable }, + { SNMP_ERR_COMMITFAILED, ErrorInfo::ErrCommitFailed }, + { SNMP_ERR_UNDOFAILED, ErrorInfo::ErrUndoFailed }, + { SNMP_ERR_AUTHORIZATIONERROR, ErrorInfo::ErrAuthorizationFailed }, + { SNMP_ERR_NOTWRITABLE, ErrorInfo::ErrNotWritable }, + { SNMP_ERR_INCONSISTENTNAME, ErrorInfo::ErrInconsistentName }, + + { SNMPERR_SUCCESS, ErrorInfo::NoError } +}; + +ErrorInfo::ErrorType KSim::Snmp::convertSnmpLibErrorToErrorInfo( int error ) +{ + for ( uint i = 0; errorMap[ i ].errorCode != SNMPERR_SUCCESS; ++i ) + if ( errorMap[ i ].errorCode == error ) + return errorMap[ i ].enumValue; + return ErrorInfo::ErrUnknown; +} + +int KSim::Snmp::convertErrorInfoToSnmpLibError( ErrorInfo::ErrorType error ) +{ + for ( uint i = 0; errorMap[ i ].errorCode != SNMPERR_SUCCESS; ++i ) + if ( errorMap[ i ].enumValue == error ) + return errorMap[ i ].errorCode; + assert( false ); + return SNMPERR_SUCCESS; +} + +int KSim::Snmp::sessionErrorCode( netsnmp_session &session ) +{ + int errorCode = 0; + SnmpLib::self()->snmp_error( &session, 0, &errorCode, 0 ); + return errorCode; +} + +static QString messageForErrorCode( int errorCode ) +{ + if ( errorCode >= SNMPERR_MAX && errorCode <= SNMPERR_GENERR ) + return QString::fromLatin1( SnmpLib::self()->snmp_api_errstring( errorCode ) ); + if ( errorCode >= SNMP_ERR_NOERROR && errorCode <= MAX_SNMP_ERR ) + return QString::fromLatin1( SnmpLib::self()->snmp_errstring( errorCode ) ); + + return QString::null; +} + +ErrorInfo::ErrorInfo() +{ + m_errorCode = NoError; +} + +ErrorInfo::ErrorInfo( int internalErrorCode ) +{ + m_errorCode = convertSnmpLibErrorToErrorInfo( internalErrorCode ); + m_errorMessage = messageForErrorCode( internalErrorCode ); +} + +ErrorInfo::ErrorInfo( ErrorType error ) +{ + m_errorCode = error; + if ( error != NoError && error != ErrUnknown ) + m_errorMessage = messageForErrorCode( convertErrorInfoToSnmpLibError( error ) ); +} + +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/snmp.h b/ksim/monitors/snmp/snmp.h new file mode 100644 index 0000000..4710c2d --- /dev/null +++ b/ksim/monitors/snmp/snmp.h @@ -0,0 +1,165 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + 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; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KSIM_SNMP_H +#define KSIM_SNMP_H + +#include <kconfigbase.h> + +#include <qmap.h> + + +namespace KSim +{ + +namespace Snmp +{ + +enum SnmpVersion { SnmpVersion1, SnmpVersion2c, SnmpVersion3, SnmpLastVersion }; +QStringList allSnmpVersions(); +QString snmpVersionToString( SnmpVersion version ); +SnmpVersion stringToSnmpVersion( QString string, bool *ok = 0 ); + +enum SecurityLevel { NoAuthPriv, AuthNoPriv, AuthPriv, LastSecurityLevel }; +QStringList allSecurityLevels(); +QString securityLevelToString( SecurityLevel level ); +SecurityLevel stringToSecurityLevel( QString string, bool *ok = 0 ); + +enum AuthenticationProtocol { MD5Auth, SHA1Auth, LastAuthenticationProtocol }; +QStringList allAuthenticationProtocols(); +QString authenticationProtocolToString( AuthenticationProtocol proto ); +AuthenticationProtocol stringToAuthenticationProtocol( QString string, bool *ok = 0 ); + +enum PrivacyProtocol { DESPrivacy }; +QStringList allPrivacyProtocols(); +QString privacyProtocolToString( PrivacyProtocol proto ); +PrivacyProtocol stringToPrivacyProtocol( QString string, bool *ok = 0 ); + +class ErrorInfo +{ +public: + enum ErrorType { + NoError = 0, + ErrUnknown, // ... if we forgot a mapping of error codes + + // api errors + ErrGeneric, + ErrInvalidLocalPort, + ErrUnknownHost, + ErrUnknownSession, + ErrTooLong, + ErrNoSocket, + ErrCannotSendV2PDUOnV1Session, + ErrCannotSendV1PDUOnV2Session, + ErrBadValueForNonRepeaters, + ErrBadValueForMaxRepetitions, + ErrBuildingASN1Representation, + ErrFailureInSendto, + ErrBadParseOfASN1Type, + ErrBadVersion, + ErrBadSourceParty, + ErrBadDestinationParty, + ErrBadContext, + ErrBadCommunity, + ErrCannotSendNoAuthDesPriv, + ErrBadACL, + ErrBadParty, + ErrSessionAbortFailure, + ErrUnknownPDU, + ErrTimeout, + ErrFailureInRecvfrom, + ErrUnableToDetermineContextEngineID, + ErrNoSecurityName, + ErrUnableToDetermineSecurityLevel, + ErrASN1ParseError, + ErrUnknownSecurityModel, + ErrInvalidMessage, + ErrUnknownEngineID, + ErrUnknownUserName, + ErrUnsupportedSecurityLevel, + ErrAuthenticationFailure, + ErrNotInTimeWindow, + ErrDecryptionError, + ErrSCAPIGeneralFailure, + ErrSCAPISubSystemNotConfigured, + ErrNoKeyTools, + ErrUnknownReport, + ErrUSMGenericError, + ErrUSMUnknownSecurityName, + ErrUSMUnsupportedSecurityLevel, + ErrUSMEncryptionError, + ErrUSMAuthenticationFailure, + ErrUSMParseError, + ErrUSMUnknownEngineID, + ErrUSMNotInTimeWindow, + ErrUSMDecryptionError, + ErrMIBNotInitialized, + ErrValueOutOfRange, + ErrSubIdOutOfRange, + ErrBadSubIdInOID, + ErrOIDTooLong, + ErrBadValueName, + ErrBadValueNotation, + ErrUnknownOID, + ErrNullPDU, + ErrMissingVariables, + ErrBadVariableType, + ErrOOM, + ErrKerberos, + + // pdu response errors + + ErrResponseTooLarge, + ErrNoSuchVariable, + ErrBadValue, + ErrReadOnly, + ErrNoAccess, + ErrWrongType, + ErrWrongLength, + ErrWrongEncoding, + ErrWrongValue, + ErrNoCreation, + ErrInconsistentValue, + ErrResourceUnavailable, + ErrCommitFailed, + ErrUndoFailed, + ErrAuthorizationFailed, + ErrNotWritable, + ErrInconsistentName + }; + + ErrorInfo(); + ErrorInfo( int internalErrorCode ); + ErrorInfo( ErrorType error ); + + ErrorType errorCode() const { return m_errorCode; } + QString errorMessage() const { return m_errorMessage; } + +private: + ErrorType m_errorCode; + QString m_errorMessage; +}; + +} + +} + +#endif // KSIMSNMP_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/snmp_p.h b/ksim/monitors/snmp/snmp_p.h new file mode 100644 index 0000000..9d96868 --- /dev/null +++ b/ksim/monitors/snmp/snmp_p.h @@ -0,0 +1,59 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + 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; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef SNMP_P_H +#define SNMP_P_H + +#define HAVE_STRLCPY 1 +#include <net-snmp/net-snmp-config.h> +#include <net-snmp/net-snmp-includes.h> + +#include "snmp.h" +#include "identifier.h" + +namespace KSim +{ + +namespace Snmp +{ + +ErrorInfo::ErrorType convertSnmpLibErrorToErrorInfo( int error ); +int convertErrorInfoToSnmpLibError( ErrorInfo::ErrorType error ); + +int snmpVersionToSnmpLibConstant( SnmpVersion version ); +int snmpSecurityLevelToSnmpLibConstant( SecurityLevel secLevel ); + +int sessionErrorCode( netsnmp_session &session ); + +struct Identifier::Data +{ + Data() : length( 0 ) {} + Data( const oid *d, size_t length ); + + oid data[ MAX_OID_LEN ]; + size_t length; +}; + +} + +} + +#endif // SNMP_P_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/snmplib.cpp b/ksim/monitors/snmp/snmplib.cpp new file mode 100644 index 0000000..a063203 --- /dev/null +++ b/ksim/monitors/snmp/snmplib.cpp @@ -0,0 +1,151 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + 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; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "snmplib.h" +#include "snmp_p.h" + +#include <kstaticdeleter.h> + +using namespace KSim::Snmp; + +SnmpLib *SnmpLib::s_self; + +::KStaticDeleter<KSim::Snmp::SnmpLib> sd; + +SnmpLib::SnmpLib() +{ + m_lockHelper = new ClassLocker<SnmpLib>( &m_guard, this ); + + init_snmp( "ksim" ); +} + +SnmpLib::~SnmpLib() +{ + delete m_lockHelper; +} + +ClassLocker<SnmpLib> &SnmpLib::self() +{ + if ( !s_self ) { + static QMutex singletonGuard; + + QMutexLocker locker( &singletonGuard ); + if ( !s_self ) + sd.setObject( s_self, new SnmpLib ); + } + return *s_self->m_lockHelper; +} + +oid *SnmpLib::snmp_parse_oid( const char *name, oid *oid, size_t *length ) +{ + return ::snmp_parse_oid( name, oid, length ); +} + +int SnmpLib::netsnmp_ds_set_int( int storeid, int which, int value ) +{ + return ::netsnmp_ds_set_int( storeid, which, value ); +} + +int SnmpLib::netsnmp_ds_get_int( int storeid, int which ) +{ + return ::netsnmp_ds_get_int( storeid, which ); +} + +struct tree *SnmpLib::netsnmp_sprint_realloc_objid_tree( u_char ** buf, + size_t * buf_len, + size_t * out_len, + int allow_realloc, + int *buf_overflow, + const oid * objid, + size_t objidlen ) +{ + return ::netsnmp_sprint_realloc_objid_tree( buf, buf_len, out_len, allow_realloc, buf_overflow, objid, objidlen ); +} + +int SnmpLib::netsnmp_oid_equals( const oid *firstOid, size_t firstOidLen, const oid *secondOid, size_t secondOidLen ) +{ + return ::netsnmp_oid_equals( firstOid, firstOidLen, secondOid, secondOidLen ); +} + +int SnmpLib::snmp_oid_compare( const oid *firstOid, size_t firstOidLen, const oid *secondOid, size_t secondOidLen ) +{ + return ::snmp_oid_compare( firstOid, firstOidLen, secondOid, secondOidLen ); +} + +void SnmpLib::snmp_error( netsnmp_session *session, int *p_errno, int *p_snmp_errno, char **p_str ) +{ + ::snmp_error( session, p_errno, p_snmp_errno, p_str ); +} + +const char *SnmpLib::snmp_api_errstring( int code ) +{ + return ::snmp_api_errstring( code ); +} + +const char *SnmpLib::snmp_errstring( int code ) +{ + return ::snmp_errstring( code ); +} + +netsnmp_pdu *SnmpLib::snmp_pdu_create( int pduType ) +{ + return ::snmp_pdu_create( pduType ); +} + +void SnmpLib::snmp_free_pdu( netsnmp_pdu *pdu ) +{ + ::snmp_free_pdu( pdu ); +} + +netsnmp_variable_list *SnmpLib::snmp_add_null_var( netsnmp_pdu *pdu, oid *var, size_t varlen ) +{ + return ::snmp_add_null_var( pdu, var, varlen ); +} + +void SnmpLib::snmp_sess_init( netsnmp_session *session ) +{ + ::snmp_sess_init( session ); +} + +netsnmp_session *SnmpLib::snmp_open( netsnmp_session *session ) +{ + return ::snmp_open( session ); +} + +int SnmpLib::snmp_close( netsnmp_session *session ) +{ + return ::snmp_close( session ); +} + +int SnmpLib::snmp_synch_response( netsnmp_session *session, netsnmp_pdu *pdu, + netsnmp_pdu **response ) +{ + return ::snmp_synch_response( session, pdu, response ); +} + +int SnmpLib::generate_Ku( const oid * hashtype, u_int hashtype_len, + u_char * P, size_t pplen, + u_char * Ku, size_t * kulen ) +{ + return ::generate_Ku( hashtype, hashtype_len, P, pplen, Ku, kulen ); +} + +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/snmplib.h b/ksim/monitors/snmp/snmplib.h new file mode 100644 index 0000000..e8b14a4 --- /dev/null +++ b/ksim/monitors/snmp/snmplib.h @@ -0,0 +1,143 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + 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; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef SNMPLIB_H +#define SNMPLIB_H + +// ### REMOVEME: move snmplib somewhere else +#define HAVE_STRLCPY 1 +#include <net-snmp/net-snmp-config.h> +#include <net-snmp/net-snmp-includes.h> + +#include <qmutex.h> + +template <class> class KStaticDeleter; + +namespace KSim +{ + +namespace Snmp +{ + +template <class T> +class ClassLocker +{ +public: + ClassLocker( QMutex *guard, T *obj ) + : m_guard( guard ), m_obj( obj ) + {} + + struct ClassLockerHelper + { + ClassLockerHelper( QMutex *guard, T *obj ) + : m_guard( guard ), m_obj( obj ), m_locked( false ) + {} + + ~ClassLockerHelper() + { + if ( m_locked ) + m_guard->unlock(); + } + + T *operator->() + { + m_guard->lock(); + m_locked = true; + return m_obj; + } + + private: + QMutex *m_guard; + T *m_obj; + bool m_locked; + }; + + ClassLockerHelper operator->() + { + return ClassLockerHelper( m_guard, m_obj ); + } + +private: + ClassLocker( const ClassLocker & ); + ClassLocker &operator=( const ClassLocker & ); + + QMutex *m_guard; + T *m_obj; +}; + +class SnmpLib +{ + friend class KStaticDeleter<SnmpLib>; +public: + + static ClassLocker<SnmpLib> &self(); + + oid *snmp_parse_oid( const char *name, oid *oid, size_t *length ); + + int netsnmp_ds_set_int( int storeid, int which, int value ); + int netsnmp_ds_get_int( int storeid, int which ); + + struct tree *netsnmp_sprint_realloc_objid_tree( u_char ** buf, + size_t * buf_len, + size_t * out_len, + int allow_realloc, + int *buf_overflow, + const oid * objid, + size_t objidlen ); + + int netsnmp_oid_equals( const oid *firstOid, size_t firstOidLen, const oid *secondOid, size_t secondOidLen ); + int snmp_oid_compare( const oid *firstOid, size_t firstOidLen, const oid *secondOid, size_t secondOidLen ); + + void snmp_error( netsnmp_session *session, int *p_errno, int *p_snmp_errno, char **p_str ); + const char *snmp_api_errstring( int code ); + const char *snmp_errstring( int code ); + + netsnmp_pdu *snmp_pdu_create( int pduType ); + void snmp_free_pdu( netsnmp_pdu *pdu ); + netsnmp_variable_list *snmp_add_null_var( netsnmp_pdu *pdu, oid *var, size_t varlen ); + + void snmp_sess_init( netsnmp_session *session ); + netsnmp_session *snmp_open( netsnmp_session *session ); + int snmp_close( netsnmp_session *session ); + + int snmp_synch_response( netsnmp_session *session, netsnmp_pdu *pdu, + netsnmp_pdu **response ); + + int generate_Ku( const oid * hashtype, u_int hashtype_len, + u_char * P, size_t pplen, + u_char * Ku, size_t * kulen ); + +private: + SnmpLib(); + ~SnmpLib(); + + QMutex m_guard; + ClassLocker<SnmpLib> *m_lockHelper; + + static SnmpLib *s_self; +}; + +} +} + + +#endif // SNMPLIB_H +/* vim: et sw=4 ts=4 + */ + diff --git a/ksim/monitors/snmp/value.cpp b/ksim/monitors/snmp/value.cpp new file mode 100644 index 0000000..fe42a08 --- /dev/null +++ b/ksim/monitors/snmp/value.cpp @@ -0,0 +1,333 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + 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; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "value.h" +#include "value_p.h" +#include "snmp_p.h" + +#include <qvariant.h> + +#include <klocale.h> + +#include <assert.h> + +using namespace KSim::Snmp; + +ValueImpl::ValueImpl( variable_list *var ) +{ + switch ( var->type ) { + case ASN_INTEGER: { + type = Value::Int; + data = QVariant( static_cast<int>( *var->val.integer ) ); + break; + } + case ASN_UINTEGER: { + type = Value::UInt; + data = QVariant( static_cast<uint>( *var->val.integer ) ); + break; + } + case ASN_OCTET_STR: { + type = Value::ByteArray; + QByteArray d; + d.setRawData( reinterpret_cast<char *>( var->val.string ), var->val_len ); + QByteArray copy = d; + copy.detach(); + d.resetRawData( reinterpret_cast<char *>( var->val.string ), var->val_len ); + data = QVariant( copy ); + break; + } + case ASN_NULL: { + type = Value::Null; + break; + } + case ASN_OBJECT_ID: { + type = Value::Oid; + oid = Identifier( new Identifier::Data( var->val.objid, var->val_len / sizeof( oid ) ) ); + break; + } + case ASN_IPADDRESS: { + type = Value::IpAddress; + addr = QHostAddress( static_cast<uint>( *var->val.integer ) ); + break; + } + case ASN_COUNTER: { + type = Value::Counter; + data = QVariant( static_cast<uint>( *var->val.integer ) ); + break; + } + case ASN_GAUGE: { + type = Value::Gauge; + data = QVariant( static_cast<uint>( *var->val.integer ) ); + break; + } + case ASN_COUNTER64: { + type = Value::Counter64; + ctr64 = ( ( ( Q_UINT64 )var->val.counter64->high ) << 32 ) | ( var->val.counter64->low ); + break; + } + case ASN_TIMETICKS: { + type = Value::TimeTicks; + data = QVariant( static_cast<int>( *var->val.integer ) ); + break; + } + case SNMP_NOSUCHOBJECT: { + type = Value::NoSuchObject; + break; + } + case SNMP_NOSUCHINSTANCE: { + type = Value::NoSuchInstance; + break; + } + case SNMP_ENDOFMIBVIEW: { + type = Value::EndOfMIBView; + break; + } +#if defined( OPAQUE_SPECIAL_TYPES ) + case ASN_OPAQUE_FLOAT: { + type = Value::Double; + data = QVariant( static_cast<float>( *var->val.floatVal ) ); + break; + } + case ASN_OPAQUE_DOUBLE: { + type = Value::Double; + data = QVariant( static_cast<float>( *var->val.doubleVal ) ); + break; + } +#endif + default: { + qDebug( "ValueImp: converting from %i to invalid", var->type ); + type = Value::Invalid; break; + } + } +} + +Value::Value() +{ + d = new ValueImpl; +} + +Value::Value( ValueImpl *impl ) + : d( impl ) +{ +} + +Value::Value( int val, Type type ) +{ + d = new ValueImpl; + + assert( type == Int || type == TimeTicks ); + + d->type = type; + d->data = QVariant( val ); +} + +Value::Value( uint val, Type type ) +{ + d = new ValueImpl; + + assert( type == UInt || type == Counter || type == Gauge ); + + d->type = type; + d->data = QVariant( val ); +} + +Value::Value( double val ) +{ + d = new ValueImpl; + d->type = Double; + d->data = QVariant( val ); +} + +Value::Value( const QByteArray &data ) +{ + d = new ValueImpl; + d->type = ByteArray; + d->data = QVariant( data ); +} + +Value::Value( const KSim::Snmp::Identifier &oid ) +{ + d = new ValueImpl; + d->type = Value::Oid; + d->oid = oid; +} + +Value::Value( const QHostAddress &address ) +{ + d = new ValueImpl; + d->type = IpAddress; + d->addr = address; +} + +Value::Value( Q_UINT64 counter ) +{ + d = new ValueImpl; + d->type = Counter64; + d->ctr64 = counter; +} + +Value::Value( const Value &rhs ) +{ + d = new ValueImpl( *rhs.d ); +} + +Value &Value::operator=( const Value &rhs ) +{ + if ( this == &rhs ) + return *this; + + delete d; + d = new ValueImpl( *rhs.d ); + + return *this; +} + +Value::~Value() +{ + delete d; +} + +Value::Type Value::type() const +{ + return d->type; +} + +int Value::toInt() const +{ + switch ( d->type ) { + case Int: + case TimeTicks: return d->data.toInt(); + case Invalid: qDebug( "cannot convert from invalid to int" ); + default: assert( false ); + } + assert( false ); + return -1; +} + +uint Value::toUInt() const +{ + switch ( d->type ) { + case UInt: + case Counter: + case Gauge: return d->data.toUInt(); + case Invalid: qDebug( "cannot convert from invalid to uint" ); + default: assert( false ); + } + assert( false ); + return 0; +} + +double Value::toDouble() const +{ + assert( d->type == Double ); + return d->data.toDouble(); +} + +const QByteArray Value::toByteArray() const +{ + assert( d->type == ByteArray ); + return d->data.toByteArray(); +} + +const Identifier Value::toOID() const +{ + assert( d->type == Oid ); + return d->oid; +} + +const QHostAddress Value::toIpAddress() const +{ + assert( d->type == IpAddress ); + return d->addr; +} + +uint Value::toCounter() const +{ + return toUInt(); +} + +uint Value::toGauge() const +{ + return toUInt(); +} + +int Value::toTimeTicks() const +{ + return toInt(); +} + +Q_UINT64 Value::toCounter64() const +{ + assert( d->type == Counter64 ); + return d->ctr64; +} + +QString Value::toString( int conversionFlags ) const +{ + switch ( type() ) { + case Value::Int: return QString::number( toInt() ); + case Value::Gauge: + case Value::Counter: + case Value::UInt: return QString::number( toUInt() ); + case Value::Double: return QString::number( toDouble() ); + case Value::Counter64: return QString::number( toCounter64() ); + case Value::ByteArray: return QString::fromAscii( toByteArray().data(), toByteArray().size() ); + case Value::IpAddress: return toIpAddress().toString(); + case Value::Oid: return toOID().toString(); + case Value::TimeTicks: return formatTimeTicks( toTimeTicks(), conversionFlags ); + // not using i18n here, because it may be called from within a worker thread, and I'm + // not sure it makes sense to translate it anyway + case Value::NoSuchObject: return QString::fromLatin1( "No Such Object" ); + case Value::NoSuchInstance: return QString::fromLatin1( "No Such Instance" ); + case Value::EndOfMIBView: return QString::fromLatin1( "End Of MIB View" ); + case Value::Invalid: + case Value::Null: return QString::null; + } + return QString::null; +} + +QString Value::formatTimeTicks( int ticks, int conversionFlags ) +{ + ticks /= 100; + + int days = ticks / ( 60 * 60 * 24 ); + ticks %= 60 * 60 * 24; + + int hours = ticks / ( 60 * 60 ); + ticks %= 60 * 60; + + int minutes = ticks / 60; + int seconds = ticks % 60; + + QString result; + + if ( days > 0 ) + result += QString::number( days ) + "d:"; + + result += QString::fromAscii( "%1h:%2m" ).arg( hours ).arg( minutes ); + + if ( conversionFlags & TimeTicksWithSeconds ) + result += ":" + QString::number( seconds ) + "s"; + + return result; +} + +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/value.h b/ksim/monitors/snmp/value.h new file mode 100644 index 0000000..4ffdcbb --- /dev/null +++ b/ksim/monitors/snmp/value.h @@ -0,0 +1,106 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + 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; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef VALUE_H +#define VALUE_H + +#include <qhostaddress.h> + +namespace KSim +{ + +namespace Snmp +{ + +class ValueImpl; + +class Identifier; + +struct ValueImpl; + +class Value +{ +public: + enum Type { + Invalid, + Int, + UInt, + Double, + ByteArray, + Null, + Oid, + IpAddress, + Counter, + Gauge, + TimeTicks, + Counter64, + NoSuchObject, + NoSuchInstance, + EndOfMIBView + }; + + enum StringConversionFlags { TimeTicksWithSeconds = 0x1 }; + + Value(); + + Value( ValueImpl *imp ); + + Value( int val, Type type ); + Value( uint val, Type type ); + Value( float val ); + Value( double val ); + Value( const QByteArray &data ); + Value( const Identifier &oid ); + Value( const QHostAddress &address ); + Value( Q_UINT64 counter ); + + Value( const Value &rhs ); + Value &operator=( const Value &rhs ); + ~Value(); + + Type type() const; + + bool isCounterType() const { return type() == Value::Counter || type() == Value::Counter64; } + + int toInt() const; + uint toUInt() const; + double toDouble() const; + const QByteArray toByteArray() const; + const Identifier toOID() const; + const QHostAddress toIpAddress() const; + uint toCounter() const; + uint toGauge() const; + int toTimeTicks() const; + Q_UINT64 toCounter64() const; + + QString toString( int conversionFlags = 0 ) const; + +private: + static QString formatTimeTicks( int ticks, int conversionFlags ); + + ValueImpl *d; +}; + +} + +} + +#endif // VALUE_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/value_p.h b/ksim/monitors/snmp/value_p.h new file mode 100644 index 0000000..8d61f59 --- /dev/null +++ b/ksim/monitors/snmp/value_p.h @@ -0,0 +1,63 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + 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; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef VALUE_P_H +#define VALUE_P_H + +#define HAVE_STRLCPY 1 +#include <net-snmp/net-snmp-config.h> +#include <net-snmp/net-snmp-includes.h> + +#include <qvariant.h> + +#include "identifier.h" + +namespace KSim +{ + +namespace Snmp +{ + +struct ValueImpl +{ + ValueImpl() + : type( Value::Invalid ) + {} + + ValueImpl( const ValueImpl &rhs ) + { + ( *this ) = rhs; + } + + ValueImpl( variable_list *var ); + + Value::Type type; + QVariant data; + Identifier oid; + QHostAddress addr; + Q_UINT64 ctr64; +}; + +} + +} + +#endif // VALUE_P_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/view.cpp b/ksim/monitors/snmp/view.cpp new file mode 100644 index 0000000..0a4b276 --- /dev/null +++ b/ksim/monitors/snmp/view.cpp @@ -0,0 +1,80 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + 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; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "view.h" +#include "plugin.h" +#include "monitorconfig.h" + +#include <label.h> + +#include <qlayout.h> + +#include <kconfig.h> + +using namespace KSim::Snmp; + +View::View( Plugin *parent, const char *name ) + : KSim::PluginView( parent, name ) +{ + m_layout = new QVBoxLayout( this ); + + reparseConfig(); +} + +View::~View() +{ +} + +void View::reparseConfig() +{ + m_widgets.setAutoDelete( true ); + m_widgets.clear(); + m_widgets.setAutoDelete( false ); + + KConfig &cfg = *config(); + cfg.setGroup( "General" ); + QStringList allHosts = cfg.readListEntry( "Hosts" ); + QStringList monitors = cfg.readListEntry( "Monitors" ); + + HostConfigMap hosts; + hosts.load( cfg, allHosts ); + + MonitorConfigMap monitorConfigs; + monitorConfigs.load( cfg, monitors, hosts ); + + for ( MonitorConfigMap::ConstIterator it = monitorConfigs.begin(); + it != monitorConfigs.end(); ++it ) { + + MonitorConfig monitorConfig = *it; + + QWidget *w = monitorConfig.createMonitorWidget( this ); + if ( !w ) + continue; + + m_widgets.append( w ); + m_layout->addWidget( w ); + + w->show(); + } +} + +#include "view.moc" + +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/view.h b/ksim/monitors/snmp/view.h new file mode 100644 index 0000000..f03a59c --- /dev/null +++ b/ksim/monitors/snmp/view.h @@ -0,0 +1,55 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + 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; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef VIEW_H +#define VIEW_H + +#include <pluginmodule.h> + +class QBoxLayout; + +namespace KSim +{ + +namespace Snmp +{ + +class Plugin; + +class View : public KSim::PluginView +{ + Q_OBJECT +public: + View( Plugin *parent, const char *name ); + ~View(); + + virtual void reparseConfig(); + +private: + QPtrList<QWidget> m_widgets; + QBoxLayout *m_layout; +}; + +} + +} + +#endif // VIEW_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/walker.cpp b/ksim/monitors/snmp/walker.cpp new file mode 100644 index 0000000..593cd04 --- /dev/null +++ b/ksim/monitors/snmp/walker.cpp @@ -0,0 +1,121 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + 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; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "walker.h" + +#include <qapplication.h> + +#include <functional> +#include <algorithm> + +using namespace KSim::Snmp; + +namespace +{ + template <class T> + struct Deleter : public std::unary_function<T, void> + { + void operator()( T arg ) + { delete arg; } + }; +} + +static const uint walkerRefresh = 0; + +Walker::Walker( const HostConfig &host, const Identifier &startOid, QObject *parent, const char *name ) + : QObject( parent, name ), m_stop( false ), m_oid( startOid ), m_session( host ) +{ + m_timerId = startTimer( walkerRefresh ); + start(); +} + +Walker::~Walker() +{ + m_stopGuard.lock(); + m_stop = true; + m_stopGuard.unlock(); + + if ( QThread::running() ) + QThread::wait(); + + std::for_each( m_results.begin(), m_results.end(), Deleter<Result *>() ); +} + +void Walker::run() +{ + while ( !m_stop ) { + Result *result = new Result; + + result->success = m_session.snmpGetNext( m_oid, result->data, &result->error ); + result->oid = m_oid; + + // do it here, because it sometimes is slow and can block for a bit + if ( result->success ) { + result->identifierString = result->oid.toString(); + result->dataString = result->data.toString(); + } + + m_stopGuard.lock(); + if ( !m_stop ) + m_stop = !result->success; + m_stopGuard.unlock(); + + m_resultGuard.lock(); + m_results << result; + m_resultGuard.unlock(); + } + + // cause finished signal to be emitted + QApplication::postEvent( this, new QCustomEvent( QEvent::User ) ); +} + +void Walker::timerEvent( QTimerEvent *ev ) +{ + if ( ev->timerId() != m_timerId ) + return; + + Result *result = 0; + + m_resultGuard.lock(); + if ( !m_results.isEmpty() ) { + result = m_results.first(); + m_results.remove( m_results.begin() ); + } + m_resultGuard.unlock(); + + if ( result ) { + emit resultReady( *result ); + + delete result; + } + + if ( !QThread::running() && !result ) { + killTimer( m_timerId ); + m_timerId = 0; + } +} + +void Walker::customEvent( QCustomEvent * ) +{ + emit finished(); +} + +#include "walker.moc" +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/monitors/snmp/walker.h b/ksim/monitors/snmp/walker.h new file mode 100644 index 0000000..e1b1ace --- /dev/null +++ b/ksim/monitors/snmp/walker.h @@ -0,0 +1,82 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Simon Hausmann <hausmann@kde.org> + + 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; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef WALKER_H +#define WALKER_H + +#include <qthread.h> +#include <qobject.h> +#include <qmutex.h> +#include <qvaluelist.h> + +#include "session.h" + +namespace KSim +{ + +namespace Snmp +{ + +class Walker : public QObject, public QThread +{ + Q_OBJECT +public: + Walker( const HostConfig &host, const Identifier &startOid, QObject *parent, const char *name = 0 ); + virtual ~Walker(); + + struct Result + { + Result() : success( false ) {} + bool success; + Identifier oid; + QString identifierString; + Value data; + QString dataString; + ErrorInfo error; + }; + +signals: + void resultReady( const Walker::Result &result ); + void finished(); + +protected: + virtual void run(); + virtual void timerEvent( QTimerEvent *ev ); + virtual void customEvent( QCustomEvent *ev ); + +private: + typedef QValueList<Result *> ResultList; + + ResultList m_results; + QMutex m_resultGuard; + + bool m_stop; + QMutex m_stopGuard; + + Identifier m_oid; + int m_timerId; + Session m_session; +}; + +} +} + +#endif // WALKER_H +/* vim: et sw=4 ts=4 + */ diff --git a/ksim/pics/Makefile.am b/ksim/pics/Makefile.am new file mode 100644 index 0000000..1cceeb0 --- /dev/null +++ b/ksim/pics/Makefile.am @@ -0,0 +1,2 @@ +SUBDIRS = misc +KDE_ICON = AUTO diff --git a/ksim/pics/cr16-app-ksim.png b/ksim/pics/cr16-app-ksim.png Binary files differnew file mode 100644 index 0000000..60c99da --- /dev/null +++ b/ksim/pics/cr16-app-ksim.png diff --git a/ksim/pics/cr32-app-ksim.png b/ksim/pics/cr32-app-ksim.png Binary files differnew file mode 100644 index 0000000..f889a5a --- /dev/null +++ b/ksim/pics/cr32-app-ksim.png diff --git a/ksim/pics/cr48-app-ksim.png b/ksim/pics/cr48-app-ksim.png Binary files differnew file mode 100644 index 0000000..e7a7bd3 --- /dev/null +++ b/ksim/pics/cr48-app-ksim.png diff --git a/ksim/pics/misc/Makefile.am b/ksim/pics/misc/Makefile.am new file mode 100644 index 0000000..64229a0 --- /dev/null +++ b/ksim/pics/misc/Makefile.am @@ -0,0 +1,5 @@ +ksim_images = clock.png uptime.png +EXTRA_DIST = $(ksim_images) + +images_DATA = $(ksim_images) +imagesdir = $(kde_datadir)/ksim/pics diff --git a/ksim/pics/misc/clock.png b/ksim/pics/misc/clock.png Binary files differnew file mode 100644 index 0000000..dca2c7e --- /dev/null +++ b/ksim/pics/misc/clock.png diff --git a/ksim/pics/misc/uptime.png b/ksim/pics/misc/uptime.png Binary files differnew file mode 100644 index 0000000..08e90f7 --- /dev/null +++ b/ksim/pics/misc/uptime.png diff --git a/ksim/systeminfo.cpp b/ksim/systeminfo.cpp new file mode 100644 index 0000000..567477c --- /dev/null +++ b/ksim/systeminfo.cpp @@ -0,0 +1,277 @@ +/* System Information + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <string.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include "systeminfo.h" + +#ifdef __linux__ +#include <sys/sysinfo.h> +#include <linux/kernel.h> +#endif + +#ifdef HAVE_SYS_LOADAVG_H +#include <sys/loadavg.h> +#endif + +#ifdef __FreeBSD__ +#include <osreldate.h> +#include <kvm.h> +#include <fcntl.h> +#include <sys/time.h> +#include <sys/param.h> +#include <sys/conf.h> +#if __FreeBSD_version < 400000 +#include <sys/rlist.h> +#endif +#include <sys/vmmeter.h> +#include <sys/sysctl.h> +#include <vm/vm_param.h> +#include <iomanip> +#include <iostream> +#endif + +// Some global vars +// expand as needed for other platforms +int System::bytesToMegs( unsigned long value ) +{ +#ifdef __linux__ + return ((((value / 1024) >> 10) | 11) + 1); +#endif + +#ifdef __FreeBSD__ + return (((value) + (1 << 19)) >> 20); +#endif +} + +System * System::m_self = 0; // initialize pointer +System & System::self() +{ + if ( !m_self ) + { + m_self = new System; + atexit( System::cleanup ); + } + + m_self->updateData(); + return *m_self; +} + +void System::cleanup() +{ + if ( !m_self ) + return; + + delete m_self; + m_self = 0; +} + +double System::loadAverage( int load ) const +{ + int value = --load; + return loadAverages()[ value > 2 ? 2 : value ]; +} + +System::System() +{ + m_loads[ 0 ] = 0; + m_loads[ 1 ] = 0; + m_loads[ 2 ] = 0; + + m_uptime = 0; + m_totalram = 0; + m_usedram = 0; + m_freeram = 0; + m_sharedram = 0; + m_bufferram = 0; + m_cacheram = 0; + m_totalhigh = 0; + m_freehigh = 0; + m_totalswap = 0; + m_usedswap = 0; + m_freeswap = 0; + m_procs = 0; + + m_self = this; +} + +System::~System() +{ +} + +void System::updateData() +{ +#ifdef __linux__ + struct sysinfo system; + if (sysinfo(&system) < 0) { + fprintf(stderr, "Error calling sysinfo()\n"); + return; + } + + m_uptime = system.uptime; + m_totalram = system.totalram; + m_sharedram = system.sharedram; + m_bufferram = system.bufferram; + m_usedram = m_totalram - m_freeram; + +#ifdef HAVE_SYSINFO_HIGH + m_totalhigh = system.totalhigh; + m_freehigh = system.freehigh; +#else +#ifdef __GNUC__ +#warning "TODO: find alternative way to get total high and freehigh" +#endif +#endif + + m_totalswap = system.totalswap; + m_freeswap = system.freeswap; + m_procs = system.procs; + m_cacheram = 0; + + FILE *file = fopen("/proc/meminfo", "r"); + char buffer[70]; + if (file) { + while (fgets(buffer, sizeof(buffer), file)) { + sscanf(buffer, "Mem: %*d %*d %*d %*d %*d %lu", &m_cacheram); + if (m_cacheram != 0) + break; + } + + fclose(file); + } + + m_freeram = system.freeram; +#endif + +#ifdef __FreeBSD__ + struct timeval bootTime; + size_t size = sizeof(bootTime); + + if (sysctlbyname("kern.boottime", + &bootTime, &size, NULL, 0) != -1 && bootTime.tv_sec != 0) { + m_uptime = time(0) - bootTime.tv_sec + 30; + } + + char buf[80]; + char *used; + char *total; + FILE *pipe; + static int psize = 0, pshift = 0; + static int name2oid[2] = { 0, 3 }; + struct vmtotal vmt; + size_t vmtLength = sizeof(vmt); + static char name[] = "vfs.bufspace"; + static int oidBufspace[CTL_MAXNAME + 2]; + static size_t oidBufspaceLength = sizeof(oidBufspace); + size_t bufspaceLength = sizeof(int); + static int initialized = 0; + unsigned long memXUsed, memTotal; + size_t memLength = sizeof(memTotal); + + if (pshift == 0) { + psize = getpagesize(); + while (psize > 1) { + ++pshift; + psize >>= 1; + } + } + + unsigned long xused1, xused2; + size_t xused1Length = sizeof(xused1); + size_t xused2Length = sizeof(xused2); + if (sysctlbyname("vm.stats.vm.v_active_count", &xused1, &xused1Length, NULL, 0) == 0 + && sysctlbyname("vm.stats.vm.v_inactive_count", &xused2, &xused2Length, NULL, 0) == 0) { + memXUsed = (xused1 + xused2) << pshift; + } + + unsigned long cacheRam; + size_t cacheSize = sizeof(cacheRam); + if (sysctlbyname("vm.stats.vm.v_active_count", &cacheRam, &cacheSize, NULL, 0) == 0) { + m_cacheram = cacheRam << pshift; + } + + if (!m_totalram && sysctlbyname("hw.physmem", &memTotal, &memLength, NULL, 0) == 0) + m_totalram = memTotal; + + if (sysctlbyname("vm.meter", &vmt, &vmtLength, NULL, 0) == 0) + m_sharedram = vmt.t_rmshr << pshift; + + if (!initialized) { + if (sysctl(name2oid, 2, oidBufspace, &oidBufspaceLength, + name, strlen(name)) < 0) + return; + + oidBufspaceLength /= sizeof(int); + ++initialized; + } + + if (sysctl(oidBufspace, oidBufspaceLength, + &m_bufferram, &bufspaceLength, 0, 0) < 0) + return; + + m_usedram = memXUsed - m_bufferram - m_cacheram; + m_freeram = memTotal - m_usedram; + + //TODO: get the total and free high mem values + m_totalhigh = 0; + m_freehigh = 0; + + if ((pipe = popen("/usr/sbin/swapinfo -k", "r")) == 0) { + fprintf(stderr, "Error reading swap info\n"); + m_freeswap = m_totalswap = 1; + return; + } + + fgets(buf, sizeof(buf), pipe); + fgets(buf, sizeof(buf), pipe); + fgets(buf, sizeof(buf), pipe); + fgets(buf, sizeof(buf), pipe); + pclose(pipe); + + strtok(buf, " "); + total = strtok(NULL, " "); + used = strtok(NULL, " "); + unsigned long usedSwap = atol(used) * 1024; + + m_totalswap = atol(total) * 1024; + m_freeswap = m_totalswap - usedSwap; + + //TODO: get amount of procs + m_procs = 0; +#endif + +#ifdef HAVE_GETLOADAVG + double load[3]; + if (getloadavg(load, 3) != -1) { + m_loads[0] = load[0]; + m_loads[1] = load[1]; + m_loads[2] = load[2]; + } +#else +#warning "TODO: Find an alternative method for getloadavg" +#endif + + m_usedswap = m_totalswap - m_freeswap; +} diff --git a/ksim/systeminfo.h b/ksim/systeminfo.h new file mode 100644 index 0000000..39f5a73 --- /dev/null +++ b/ksim/systeminfo.h @@ -0,0 +1,137 @@ +/* System Information + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#ifndef SYSTEMINFO_H +#define SYSTEMINFO_H + +class System +{ + public: + /** + * converts bytes to megabytes + */ + static int bytesToMegs( unsigned long ); + + /** + * @return a pointer to the instance + */ + static System & self(); + /** + * Deletes the instance and cleans up after itself + */ + static void cleanup(); + + /** + * @return the total amount of seconds + * the pc has been running + */ + long uptime() const { return m_uptime; } + /** + * @return the 3 load averages + */ + const double * loadAverages() const { return m_loads; } + /** + * this function does the same as the + * above but returns only the @ref load + * average + */ + double loadAverage( int ) const; + /** + * @return the total ram the system has + */ + unsigned long totalRam() const { return m_totalram; } + /** + * @return the total used ram + */ + unsigned long usedRam() const { return m_usedram; } + /** + * @return the total free ram the system has + */ + unsigned long freeRam() const { return m_freeram; } + /** + * @return the amount of shared + * memory in the system + */ + unsigned long sharedRam() const { return m_sharedram; } + /** + * @return the amount of buffered + * memory in the system + */ + unsigned long bufferRam() const { return m_bufferram; } + /** + * @return the amount of buffered + * memory in the system + */ + unsigned long cacheRam() const { return m_cacheram; } + /** + * @return the total amount of + * high memory + */ + unsigned long totalHigh() const { return m_totalhigh; } + /** + * @return the total amount of + * high free memory + */ + unsigned long freeHigh() const { return m_freehigh; } + /** + * @return the total amount of + * swap the system has + */ + unsigned long totalSwap() const { return m_totalswap; } + /** + * @return the total amount of + * swap used + */ + unsigned long usedSwap() const { return m_usedswap; } + /** + * @return the total amount of + * free swap the system has + */ + unsigned long freeSwap() const { return m_freeswap; } + /** + * @return the number of + * procs running + */ + unsigned short procs() const { return m_procs; } + + private: + System(); + System( const System & ); + System & operator=( const System & ); + ~System(); + + void updateData(); + + long m_uptime; // seconds since boot + double m_loads[3]; // 1, 5, and 15 minute load averages + unsigned long m_totalram; // Total usable main memory size + unsigned long m_usedram; // Used memory size + unsigned long m_freeram; // Available memory size + unsigned long m_sharedram; // Amount of shared memory + unsigned long m_bufferram; // Memory used by buffers + unsigned long m_cacheram; // Amount of cached ram + unsigned long m_totalhigh; // Total high memory size + unsigned long m_freehigh; // Available high memory size + unsigned long m_totalswap; // Total swap space size + unsigned long m_usedswap; // Used swap space size + unsigned long m_freeswap; // Swap space still available + unsigned short m_procs; // Number of current processes + static System * m_self; +}; +#endif diff --git a/ksim/themeprefs.cpp b/ksim/themeprefs.cpp new file mode 100644 index 0000000..3951f61 --- /dev/null +++ b/ksim/themeprefs.cpp @@ -0,0 +1,272 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#include "themeprefs.h" +#include "themeprefs.moc" + +#include <qdir.h> +#include <qlayout.h> +#include <qtooltip.h> +#include <qlabel.h> +#include <qregexp.h> + +#include <klocale.h> +#include <kdebug.h> +#include <kglobal.h> +#include <kstandarddirs.h> +#include <kurllabel.h> +#include <kapplication.h> +#include <kfontdialog.h> +#include <kcombobox.h> +#include <klistview.h> +#include <ksqueezedtextlabel.h> +#include <knuminput.h> +#include <kseparator.h> + +#include <ksimconfig.h> +#include <common.h> +#include <themeloader.h> + +class ThemeViewItem : public KListViewItem +{ + public: + ThemeViewItem(QListView *parent, const QString &text, + const KURL &url) : KListViewItem(parent, text) + { + m_url = url; + } + + const KURL &url() const { return m_url; } + + private: + KURL m_url; +}; + +KSim::ThemePrefs::ThemePrefs(QWidget *parent, const char *name) + : QWidget(parent, name) +{ + m_themeLayout = new QGridLayout(this); + m_themeLayout->setSpacing(6); + + m_label = new QLabel(this); + m_label->setText(i18n("GKrellm theme support. To use" + " gkrellm themes just untar the themes into the folder below")); + m_label->setAlignment(QLabel::WordBreak | + QLabel::AlignVCenter | QLabel::AlignLeft); + m_themeLayout->addMultiCellWidget(m_label, 0, 0, 0, 4); + + QString themeDir(locateLocal("data", "ksim")); + themeDir += QString::fromLatin1("/themes"); + + m_urlLabel = new KURLLabel(this); + m_urlLabel->setText(i18n("Open Konqueror in KSim's theme folder")); + m_urlLabel->setURL(QString::fromLatin1("file://") + themeDir); + connect(m_urlLabel, SIGNAL(leftClickedURL(const QString &)), + this, SLOT(openURL(const QString &))); + m_themeLayout->addMultiCellWidget(m_urlLabel, 1, 1, 0, 4); + + m_line = new KSeparator(Horizontal, this); + m_themeLayout->addMultiCellWidget(m_line, 2, 2, 0, 4); + + m_authorLabel = new QLabel(this); + m_authorLabel->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, + QSizePolicy::Minimum)); + m_authorLabel->setText(i18n("Author:")); + m_themeLayout->addMultiCellWidget(m_authorLabel, 3, 3, 0, 0); + + m_authLabel = new KSqueezedTextLabel(this); + m_authLabel->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, + QSizePolicy::Minimum)); + m_authLabel->setText(i18n("None")); + m_themeLayout->addMultiCellWidget(m_authLabel, 3, 3, 1, 4); + + m_listView = new KListView(this); + m_listView->addColumn(i18n("Theme")); + m_listView->setFullWidth(true); + connect(m_listView, SIGNAL(currentChanged(QListViewItem *)), + this, SLOT(selectItem(QListViewItem *))); + m_themeLayout->addMultiCellWidget(m_listView, 4, 4, 0, 4); + + m_alternateLabel = new QLabel(this); + m_alternateLabel->setText(i18n("Alternate themes:")); + m_alternateLabel->setAlignment(AlignVCenter | AlignRight); + m_themeLayout->addMultiCellWidget(m_alternateLabel, 5, 5, 0, 1); + + m_altTheme = new KIntSpinBox(this); + m_themeLayout->addMultiCellWidget(m_altTheme, 5, 5, 2, 2); + + m_fontLabel = new QLabel(this); + m_fontLabel->setText(i18n("Font:")); + m_fontLabel->setAlignment(AlignVCenter | AlignRight); + m_fontLabel->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, + QSizePolicy::Fixed)); + m_themeLayout->addMultiCellWidget(m_fontLabel, 5, 5, 3, 3); + + m_fontsCombo = new KComboBox(this); + m_fontsCombo->insertItem(i18n("Small")); + m_fontsCombo->insertItem(i18n("Normal")); + m_fontsCombo->insertItem(i18n("Large")); + m_fontsCombo->insertItem(i18n("Custom")); + m_fontsCombo->insertItem(i18n("Default")); + m_fontsCombo->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, + QSizePolicy::Fixed)); + connect(m_fontsCombo, SIGNAL(activated(int)), + this, SLOT(showFontDialog(int))); + m_themeLayout->addMultiCellWidget(m_fontsCombo, 5, 5, 4, 4); + + QStringList locatedFiles = KGlobal::dirs()->findDirs("data", "ksim/themes"); + for (QStringList::ConstIterator it = locatedFiles.begin(); it != locatedFiles.end(); ++it) + readThemes(*it); +} + +KSim::ThemePrefs::~ThemePrefs() +{ +} + +void KSim::ThemePrefs::saveConfig(KSim::Config *config) +{ + config->setThemeName(m_currentTheme.name); + config->setThemeAlt(m_altTheme->value()); + config->setThemeFontItem(m_fontsCombo->currentItem()); + config->setThemeFont(m_font); +} + +void KSim::ThemePrefs::readConfig(KSim::Config *config) +{ + setCurrentTheme(ThemeInfo(KSim::ThemeLoader::currentName(), + KURL( KSim::ThemeLoader::currentUrl() ), KSim::ThemeLoader::self().current().alternatives())); + m_altTheme->setValue(config->themeAlt()); + m_fontsCombo->setCurrentItem(config->themeFontItem()); + m_font = config->themeFont(); +} + +void KSim::ThemePrefs::setCurrentTheme(const ThemeInfo &theme) +{ + if (theme == m_currentTheme) + return; + + m_currentTheme = theme; + completed(); +} + +void KSim::ThemePrefs::setThemeAlts(int alternatives) +{ + m_currentTheme.alternatives = alternatives; + m_altTheme->setMaxValue(alternatives); + if (m_altTheme->value() > m_altTheme->maxValue()) + m_altTheme->setValue(m_altTheme->maxValue()); + + m_altTheme->setEnabled(alternatives == 0 ? false : true); + m_alternateLabel->setEnabled(alternatives == 0 ? false : true); +} + +void KSim::ThemePrefs::openURL(const QString &url) +{ + kapp->invokeBrowser(url); +} + +void KSim::ThemePrefs::insertItems(const ThemeInfoList &itemList) +{ + ThemeInfoList::ConstIterator it; + for (it = itemList.begin(); it != itemList.end(); ++it) { + (void) new ThemeViewItem(m_listView, (*it).name, (*it).url); + m_themeList.append((*it)); + } + + completed(); +} + +void KSim::ThemePrefs::clear() +{ + m_themeList.clear(); +} + +void KSim::ThemePrefs::completed() +{ + kdDebug(2003) << "Finished listing" << endl; + + for (QListViewItemIterator it(m_listView); it.current(); it++) + { + if (it.current()->text(0) == m_currentTheme.name) + { + m_listView->setSelected(it.current(), true); + m_listView->setCurrentItem(it.current()); + m_listView->ensureItemVisible(it.current()); + + selectItem( it.current() ); + break; + } + } +} + +void KSim::ThemePrefs::selectItem(QListViewItem *item) +{ + if (!item) + return; + + ThemeViewItem *themeItem = static_cast<ThemeViewItem *>(item); + ThemeInfoList::ConstIterator it = qFind(m_themeList.begin(), + m_themeList.end(), ThemeInfo(themeItem->text(0), themeItem->url())); + + if (it == m_themeList.end()) + return; + + m_currentTheme = (*it); + + const KSim::Theme &theme(KSim::ThemeLoader::self().theme(m_currentTheme.url.path())); + if (theme.name() != "ksim") + KSim::ThemeLoader::self().parseDir(theme.path(), theme.alternatives()); + + QToolTip::remove(m_authLabel); + if (theme.author().isEmpty()) { + m_authLabel->setText(i18n("None Specified")); + QToolTip::add(m_authLabel, i18n("None specified")); + } + else { + m_authLabel->setText(theme.author()); + QToolTip::add(m_authLabel, theme.author()); + } + + kdDebug( 2003 ) << "theme.alternatives() = " << theme.alternatives() << endl; + setThemeAlts(theme.alternatives()); +} + +void KSim::ThemePrefs::readThemes(const QString &location) +{ + kdDebug(2003) << "readThemes(" << location << ")" << endl; + ThemeInfoList themeList; + QStringList items(QDir(location).entryList(QDir::Dirs, QDir::IgnoreCase)); + QStringList::ConstIterator it; + for (it = items.begin(); it != items.end(); ++it) { + if ((*it) != "." && (*it) != "..") + themeList.append(ThemeInfo((*it), KURL(location + (*it) + "/"))); + } + + insertItems(themeList); +} + +void KSim::ThemePrefs::showFontDialog(int currentItem) +{ + if (currentItem == 3) { + QFont customFont = m_font; + int result = KFontDialog::getFont(customFont); + if (result == KFontDialog::Accepted) + m_font = customFont; + } +} diff --git a/ksim/themeprefs.h b/ksim/themeprefs.h new file mode 100644 index 0000000..8ae569e --- /dev/null +++ b/ksim/themeprefs.h @@ -0,0 +1,115 @@ +/* ksim - a system monitor for kde + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * 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. + */ + +#ifndef THEMEIMPL_H +#define THEMEIMPL_H + +#include <kurl.h> +#include <qwidget.h> + +class QListViewItem; +class QGridLayout; +class QLabel; +class KListView; +class KURLLabel; +class KComboBox; +class KSqueezedTextLabel; +class KIntSpinBox; +class KSeparator; + +namespace KSim +{ + class Config; + + class ThemeInfo + { + public: + ThemeInfo() : name(0), url(0), alternatives(0) {} + ThemeInfo(const QString &name, const KURL &url, int alts=0) + : name(name), url(url), alternatives(alts) {} + + bool operator==(const ThemeInfo &rhs) const + { + return (rhs.name == name && rhs.url == url + && rhs.alternatives == alternatives); + } + + bool operator!=(const ThemeInfo &rhs) const + { + return !(operator==(rhs)); + } + + ThemeInfo &operator=(const ThemeInfo &rhs) + { + if (*this == rhs) + return *this; + + name = rhs.name; + url = rhs.url; + alternatives = rhs.alternatives; + return *this; + } + + QString name; + KURL url; + int alternatives; + }; + + typedef QValueList<ThemeInfo> ThemeInfoList; + + class ThemePrefs : public QWidget + { + Q_OBJECT + public: + ThemePrefs(QWidget *parent, const char *name=0); + ~ThemePrefs(); + + public slots: + void saveConfig(KSim::Config *); + void readConfig(KSim::Config *); + + private slots: + void setCurrentTheme(const ThemeInfo &); + void setThemeAlts(int); + void openURL(const QString &); + void insertItems(const ThemeInfoList &); + void clear(); + void completed(); + void selectItem(QListViewItem *item); + void readThemes(const QString &); + void showFontDialog(int); + + private: + KListView *m_listView; + KURLLabel *m_urlLabel; + KIntSpinBox *m_altTheme; + KComboBox *m_fontsCombo; + QLabel *m_label; + QLabel *m_authorLabel; + KSqueezedTextLabel *m_authLabel; + QLabel *m_alternateLabel; + QLabel *m_fontLabel; + KSeparator *m_line; + ThemeInfo m_currentTheme; + QFont m_font; + ThemeInfoList m_themeList; + QGridLayout *m_themeLayout; + }; +} +#endif diff --git a/ksim/themes/Makefile.am b/ksim/themes/Makefile.am new file mode 100644 index 0000000..ccdc199 --- /dev/null +++ b/ksim/themes/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = ksim diff --git a/ksim/themes/ksim/Makefile.am b/ksim/themes/ksim/Makefile.am new file mode 100644 index 0000000..44b0dca --- /dev/null +++ b/ksim/themes/ksim/Makefile.am @@ -0,0 +1,24 @@ +theme_images = bg_grid.png \ + bg_panel.png \ + krell_meter.png \ + krell_slider.png \ + bg_chart.png \ + bg_meter.png \ + gkrellmrc \ + gkrellmrc_ksim \ + krell_panel.png \ + frame_top.png \ + frame_bottom.png \ + frame_left.png \ + frame_right.png + +net_images = decal_net_leds.png + +EXTRA_DIST = $(theme_images) $(net_images) +SUBDIRS = host mail + +theme_DATA = $(theme_images) +themedir = $(kde_datadir)/ksim/themes/ksim + +net_DATA = $(net_images) +netdir = $(kde_datadir)/ksim/themes/ksim/net diff --git a/ksim/themes/ksim/bg_chart.png b/ksim/themes/ksim/bg_chart.png Binary files differnew file mode 100644 index 0000000..e193b2b --- /dev/null +++ b/ksim/themes/ksim/bg_chart.png diff --git a/ksim/themes/ksim/bg_grid.png b/ksim/themes/ksim/bg_grid.png Binary files differnew file mode 100644 index 0000000..3d971e6 --- /dev/null +++ b/ksim/themes/ksim/bg_grid.png diff --git a/ksim/themes/ksim/bg_meter.png b/ksim/themes/ksim/bg_meter.png Binary files differnew file mode 100644 index 0000000..e49f839 --- /dev/null +++ b/ksim/themes/ksim/bg_meter.png diff --git a/ksim/themes/ksim/bg_panel.png b/ksim/themes/ksim/bg_panel.png Binary files differnew file mode 100644 index 0000000..2582eaf --- /dev/null +++ b/ksim/themes/ksim/bg_panel.png diff --git a/ksim/themes/ksim/decal_net_leds.png b/ksim/themes/ksim/decal_net_leds.png Binary files differnew file mode 100644 index 0000000..b8990c0 --- /dev/null +++ b/ksim/themes/ksim/decal_net_leds.png diff --git a/ksim/themes/ksim/frame_bottom.png b/ksim/themes/ksim/frame_bottom.png Binary files differnew file mode 100644 index 0000000..f23d03f --- /dev/null +++ b/ksim/themes/ksim/frame_bottom.png diff --git a/ksim/themes/ksim/frame_left.png b/ksim/themes/ksim/frame_left.png Binary files differnew file mode 100644 index 0000000..a7d1009 --- /dev/null +++ b/ksim/themes/ksim/frame_left.png diff --git a/ksim/themes/ksim/frame_right.png b/ksim/themes/ksim/frame_right.png Binary files differnew file mode 100644 index 0000000..63b0e7a --- /dev/null +++ b/ksim/themes/ksim/frame_right.png diff --git a/ksim/themes/ksim/frame_top.png b/ksim/themes/ksim/frame_top.png Binary files differnew file mode 100644 index 0000000..ad3cc3e --- /dev/null +++ b/ksim/themes/ksim/frame_top.png diff --git a/ksim/themes/ksim/gkrellmrc b/ksim/themes/ksim/gkrellmrc new file mode 100644 index 0000000..dc44c93 --- /dev/null +++ b/ksim/themes/ksim/gkrellmrc @@ -0,0 +1,47 @@ +author = Robbie Ward <linuxphreak@gmx.co.uk> + +# krell_meter.png taken from ShinyAll2 + +frame_top_height = 2 +frame_bottom_height = 2 +frame_left_width = 2 +frame_right_width = 2 + +chart_in_color = #7B9DDE +chart_in_color_grid = gray20 +chart_out_color = #CDE2FF +chart_out_color_grid = gray20 + +bg_grid_mode = 1 + +normal_font = -adobe-helvetica-medium-r-normal-*-*-100-*-*-p-*-iso8859-1 +large_font = -adobe-helvetica-medium-r-normal-*-*-120-*-*-p-*-iso8859-1 +small_font = -adobe-helvetica-medium-r-normal-*-*-80-*-*-p-*-iso8859-1 + +rx_led_x = 2 +rx_led_y = 3 +tx_led_x = -2 +tx_led_y = 3 + +decal_mail_frames = 18 +decal_mail_delay = 1 + +timer_time_x = 2 +timer_button_x = -2 + +krell_slider_x_hot = 1 + +StyleChart *.border = 2,2,2,2 +StyleChart *.textcolor = black white shadow + +StylePanel *.border = 2,2,2,2 +StylePanel *.textcolor = black white shadow +StylePanel *.label_position = 50 +StylePanel *.krell_depth = 4 + +StyleMeter *.border = 2,2,2,2 +StyleMeter *.textcolor = black white shadow +StyleMeter *.label_position = 50 +StyleMeter fs.label_position = 0 +StyleMeter cal.font = large_font +StyleMeter clock.font = large_font diff --git a/ksim/themes/ksim/gkrellmrc_ksim b/ksim/themes/ksim/gkrellmrc_ksim new file mode 100644 index 0000000..dc44c93 --- /dev/null +++ b/ksim/themes/ksim/gkrellmrc_ksim @@ -0,0 +1,47 @@ +author = Robbie Ward <linuxphreak@gmx.co.uk> + +# krell_meter.png taken from ShinyAll2 + +frame_top_height = 2 +frame_bottom_height = 2 +frame_left_width = 2 +frame_right_width = 2 + +chart_in_color = #7B9DDE +chart_in_color_grid = gray20 +chart_out_color = #CDE2FF +chart_out_color_grid = gray20 + +bg_grid_mode = 1 + +normal_font = -adobe-helvetica-medium-r-normal-*-*-100-*-*-p-*-iso8859-1 +large_font = -adobe-helvetica-medium-r-normal-*-*-120-*-*-p-*-iso8859-1 +small_font = -adobe-helvetica-medium-r-normal-*-*-80-*-*-p-*-iso8859-1 + +rx_led_x = 2 +rx_led_y = 3 +tx_led_x = -2 +tx_led_y = 3 + +decal_mail_frames = 18 +decal_mail_delay = 1 + +timer_time_x = 2 +timer_button_x = -2 + +krell_slider_x_hot = 1 + +StyleChart *.border = 2,2,2,2 +StyleChart *.textcolor = black white shadow + +StylePanel *.border = 2,2,2,2 +StylePanel *.textcolor = black white shadow +StylePanel *.label_position = 50 +StylePanel *.krell_depth = 4 + +StyleMeter *.border = 2,2,2,2 +StyleMeter *.textcolor = black white shadow +StyleMeter *.label_position = 50 +StyleMeter fs.label_position = 0 +StyleMeter cal.font = large_font +StyleMeter clock.font = large_font diff --git a/ksim/themes/ksim/host/Makefile.am b/ksim/themes/ksim/host/Makefile.am new file mode 100644 index 0000000..d6e8739 --- /dev/null +++ b/ksim/themes/ksim/host/Makefile.am @@ -0,0 +1,4 @@ +EXTRA_DIST = bg_meter.png +host_DATA = bg_meter.png + +hostdir = $(kde_datadir)/ksim/themes/ksim/host diff --git a/ksim/themes/ksim/host/bg_meter.png b/ksim/themes/ksim/host/bg_meter.png Binary files differnew file mode 100644 index 0000000..538c560 --- /dev/null +++ b/ksim/themes/ksim/host/bg_meter.png diff --git a/ksim/themes/ksim/krell_meter.png b/ksim/themes/ksim/krell_meter.png Binary files differnew file mode 100644 index 0000000..2222fb0 --- /dev/null +++ b/ksim/themes/ksim/krell_meter.png diff --git a/ksim/themes/ksim/krell_panel.png b/ksim/themes/ksim/krell_panel.png Binary files differnew file mode 100644 index 0000000..e9a7c8f --- /dev/null +++ b/ksim/themes/ksim/krell_panel.png diff --git a/ksim/themes/ksim/krell_slider.png b/ksim/themes/ksim/krell_slider.png Binary files differnew file mode 100644 index 0000000..5ce131d --- /dev/null +++ b/ksim/themes/ksim/krell_slider.png diff --git a/ksim/themes/ksim/mail/Makefile.am b/ksim/themes/ksim/mail/Makefile.am new file mode 100644 index 0000000..ea1fa28 --- /dev/null +++ b/ksim/themes/ksim/mail/Makefile.am @@ -0,0 +1,3 @@ +pics_DATA = decal_mail.png krell_mail_daemon.png krell_mail.png + +picsdir = $(kde_datadir)/ksim/themes/ksim/mail diff --git a/ksim/themes/ksim/mail/decal_mail.png b/ksim/themes/ksim/mail/decal_mail.png Binary files differnew file mode 100644 index 0000000..53576df --- /dev/null +++ b/ksim/themes/ksim/mail/decal_mail.png diff --git a/ksim/themes/ksim/mail/krell_mail.png b/ksim/themes/ksim/mail/krell_mail.png Binary files differnew file mode 100644 index 0000000..c92d426 --- /dev/null +++ b/ksim/themes/ksim/mail/krell_mail.png diff --git a/ksim/themes/ksim/mail/krell_mail_daemon.png b/ksim/themes/ksim/mail/krell_mail_daemon.png Binary files differnew file mode 100644 index 0000000..18eb051 --- /dev/null +++ b/ksim/themes/ksim/mail/krell_mail_daemon.png |