You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdeutils/ksim/ksimview.cpp

468 lines
13 KiB

/* 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 <tqfile.h>
#include <tqbitmap.h>
#include <tqtimer.h>
#include <tqlayout.h>
#include <tqobjectlist.h>
#include <tqpainter.h>
#include <tqcursor.h>
#include <tqpopupmenu.h>
#include <tqvbox.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"),
TQWidget(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 TQVBoxLayout(this);
m_topFrame = new KSim::Frame(KSim::Types::TopFrame, this);
m_subLayout->addWidget(m_topFrame);
m_sizeLayout = new TQHBoxLayout;
m_subLayout->addLayout(m_sizeLayout);
m_leftFrame = new KSim::Frame(KSim::Types::LeftFrame, this);
m_sizeLayout->addWidget(m_leftFrame);
m_pluginLayout = new TQBoxLayout(TQBoxLayout::TopToBottom);
m_sizeLayout->addLayout(m_pluginLayout);
TQVBoxLayout *vb = new TQVBoxLayout;
TQSpacerItem *item = new TQSpacerItem(0, 0, TQSizePolicy::Expanding, TQSizePolicy::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 {
TQCString host(hostName);
int dotLocation = host.tqfind(".");
if (!m_config->displayFqdn() && dotLocation != -1)
host.truncate(dotLocation);
m_hostLabel->setText(host);
}
vb = new TQVBoxLayout;
item = new TQSpacerItem(0, 0, TQSizePolicy::Expanding, TQSizePolicy::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(),
TQT_SIGNAL(pluginLoaded(const KSim::Plugin &)),
this, TQT_SLOT(addMonitor(const KSim::Plugin &)));
KSim::ThemeLoader::self().themeColours(this);
// load the plugins and create the plugin menu
if (loadPlugins) {
addPlugins();
}
connect(&m_tqmaskTimer, TQT_SIGNAL(timeout()), TQT_SLOT(slotMaskMainView()));
}
KSim::MainView::~MainView()
{
delete m_config;
}
void KSim::MainView::show()
{
tqmaskMainView();
TQWidget::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()
{
TQString homeDir = locateLocal("data", "ksim");
TQString themeDir = homeDir + TQString::tqfromLatin1("/themes");
TQString monitorDir = homeDir + TQString::tqfromLatin1("/monitors");
// return true if the dirs already exist
if (TQFile::exists(themeDir) && TQFile::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 TQString &KSim::MainView::hostname() const
{
return m_hostLabel->text();
}
void KSim::MainView::slotMaskMainView()
{
tqmaskMainView();
}
void KSim::MainView::tqmaskMainView()
{
if (!m_topFrame->background()->tqmask() ||
!m_leftFrame->background()->tqmask() ||
!m_rightFrame->background()->tqmask() ||
!m_bottomFrame->background()->tqmask())
{
tqtopLevelWidget()->clearMask();
return;
}
TQBitmap topPixmap(*m_topFrame->background()->tqmask());
TQBitmap leftPixmap(*m_leftFrame->background()->tqmask());
TQBitmap rightPixmap(*m_rightFrame->background()->tqmask());
TQBitmap bottomPixmap(*m_bottomFrame->background()->tqmask());
TQSize insideSize(m_pluginLayout->tqgeometry().size());
// make a cleared bigrect where we can put our pixmap tqmasks on
TQBitmap bigBitmap(tqtopLevelWidget()->size(), true);
// better return if our bitmap is null so we can avoid crashes
if (bigBitmap.isNull())
return;
TQPoint ofs = mapTo(tqtopLevelWidget(), TQPoint(0,0));
int ofsX = ofs.x();
int ofsY = ofs.y();
TQPainter painter;
painter.begin(&bigBitmap);
painter.setBrush(color1);
painter.setPen(color1);
TQRect rect = m_pluginLayout->tqgeometry();
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();
tqtopLevelWidget()->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();
tqmaskMainView();
m_topLevel->reparse();
if (emitReload)
emit reload();
kdDebug(2003) << "new view created" << endl;
}
void KSim::MainView::addPlugins()
{
TQStringList locatedFiles = KGlobal::dirs()->findAllResources("data", "ksim/monitors/*.desktop");
TQStringList::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, TQPoint(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(), TQT_SIGNAL(runCommand(const TQCString &)),
TQT_SLOT(runCommand(const TQCString &)));
// if (location > m_oldLocation)
// m_oldLocation = location;
}
void KSim::MainView::runCommand(const TQCString &name)
{
if (name.isNull())
return;
kdDebug(2003) << "runCommand(" << name.mid(5) << ")" << endl;
TQString 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, TQT_SIGNAL(reparse(bool, const KSim::ChangedPluginList &)),
this, TQT_SLOT(reparseConfig(bool, const KSim::ChangedPluginList &)));
}
m_prefDialog->exec();
destroyPref();
}
void KSim::MainView::resizeEvent(TQResizeEvent *re)
{
TQWidget::resizeEvent(re);
m_tqmaskTimer.start(0, true);
}
void KSim::MainView::paletteChange(const TQPalette &)
{
// 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;
}
}
TQSize KSim::MainView::tqsizeHint(KPanelExtension::Position p, TQSize) const
{
int width = 0;
int height = 0;
TQLayoutItem *child;
for( TQLayoutIterator it = m_pluginLayout->iterator();
(child = it.current()) != 0; ++it)
{
TQSize sz = child->tqminimumSize();
if ((p == KPanelExtension::Right) || (p == KPanelExtension::Left))
{
width = TQMAX(width, sz.width());
height += sz.height();
}
else
{
width += sz.width();
height = TQMAX(height, sz.height());
}
}
width += m_leftFrame->minimumWidth() + m_rightFrame->minimumWidth();
height += m_topFrame->minimumHeight() + m_bottomFrame->minimumHeight();
return TQSize(width, height);
}
void KSim::MainView::positionChange(Qt::Orientation o)
{
if (o == Qt::Vertical)
m_pluginLayout->setDirection(TQBoxLayout::TopToBottom);
else
m_pluginLayout->setDirection(TQBoxLayout::LeftToRight);
}