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.
tdedocker/src/customtraylabel.cpp

366 lines
11 KiB

11 years ago
/*
* Copyright (C) 2004 Girish Ramakrishnan All Rights Reserved.
*
* This 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 software 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 software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
// $Id: customtraylabel.cpp,v 1.14 2005/06/21 10:04:35 cs19713 Exp $
#include <tqsettings.h>
#include <tqpopupmenu.h>
#include <tqmessagebox.h>
#include <tqfiledialog.h>
#include <tqinputdialog.h>
#include <tqaction.h>
#include <tqtimer.h>
#include <tqsize.h>
11 years ago
#include <stdlib.h>
#include <kiconloader.h>
#include <tdeglobal.h>
#include <tdelocale.h>
11 years ago
#include "trace.h"
#include "customtraylabel.h"
#include "traylabelmgr.h"
#include "tdedocker.h"
11 years ago
CustomTrayLabel::CustomTrayLabel(Window w, TQWidget* p, const TQString& t)
: TQTrayLabel(w, p, t), mUndockWhenDead(false)
11 years ago
{
installMenu();
}
CustomTrayLabel::CustomTrayLabel(const TQStringList& argv, pid_t pid,
TQWidget* parent)
: TQTrayLabel(argv, pid, parent), mUndockWhenDead(false)
11 years ago
{
installMenu();
}
/*
* Installs a popup menu on the tray label
*/
void CustomTrayLabel::installMenu()
{
//TQPixmap tdedocker_png(TDEGlobal::iconLoader()->loadIcon("tdedocker", TDEIcon::NoGroup, TDEIcon::SizeSmall));
TQPixmap *tdedocker_png = new TQPixmap("tdedocker");
setIcon(*tdedocker_png);
11 years ago
TrayLabelMgr *tlMgr = TrayLabelMgr::instance();
mOptionsMenu = new TQPopupMenu(this);
mSessionManagement = new TQAction(i18n("Dock when session restored"), 0, this);
11 years ago
mSessionManagement->setToggleAction(true);
connect(mSessionManagement, SIGNAL(toggled(bool)),
this, SLOT(enableSessionManagement(bool)));
mSessionManagement->addTo(mOptionsMenu);
mAutoLaunch = new TQAction(i18n("Launch on startup"), 0, this);
11 years ago
mAutoLaunch->setToggleAction(true);
connect(mAutoLaunch, SIGNAL(activated()),
this, SLOT(slotSetLaunchOnStartup()));
mAutoLaunch->addTo(mOptionsMenu);
mOptionsMenu->insertItem(i18n("Set Icon"), this, SLOT(setCustomIcon()));
11 years ago
mBalloonTimeout = new TQAction(i18n("Set balloon timeout"), 0, this);
11 years ago
connect(mBalloonTimeout, SIGNAL(activated()),
this, SLOT(slotSetBalloonTimeout()));
mBalloonTimeout->addTo(mOptionsMenu);
mDockWhenObscured = new TQAction(i18n("Dock when obscured"), 0, this);
11 years ago
mDockWhenObscured->setToggleAction(true);
connect(mDockWhenObscured, SIGNAL(toggled(bool)),
this, SLOT(setDockWhenObscured(bool)));
mDockWhenObscured->addTo(mOptionsMenu);
mDockWhenMinimized = new TQAction(i18n("Dock when minimized"), 0, this);
11 years ago
mDockWhenMinimized->setToggleAction(true);
connect(mDockWhenMinimized, SIGNAL(toggled(bool)),
this, SLOT(setDockWhenMinimized(bool)));
mDockWhenMinimized->addTo(mOptionsMenu);
mDockWhenFocusLost = new TQAction(i18n("Dock when focus lost"), 0, this);
11 years ago
mDockWhenFocusLost->setToggleAction(true);
connect(mDockWhenFocusLost, SIGNAL(toggled(bool)),
this, SLOT(setDockWhenFocusLost(bool)));
mDockWhenFocusLost->addTo(mOptionsMenu);
mSkipTaskbar = new TQAction(i18n("Skip taskbar"), 0, this);
11 years ago
mSkipTaskbar->setToggleAction(true);
connect(mSkipTaskbar, SIGNAL(toggled(bool)),
this, SLOT(setSkipTaskbar(bool)));
mSkipTaskbar->addTo(mOptionsMenu);
mMainMenu = new TQPopupMenu(this);
mMainMenu->insertItem(TQIconSet(*tdedocker_png),
i18n("About TDEDocker"), tlMgr, SLOT(about()));
11 years ago
mMainMenu->insertSeparator();
mMainMenu->insertItem(i18n("Options"), mOptionsMenu);
mMainMenu->insertItem(i18n("Dock Another"), tlMgr, SLOT(dockAnother()));
mMainMenu->insertItem(i18n("Undock All"), tlMgr, SLOT(undockAll()));
11 years ago
mMainMenu->insertSeparator();
mShowId = mMainMenu->insertItem(TQString("Show/Hide [untitled]"),
11 years ago
this, SLOT(toggleShow()));
mMainMenu->insertItem(TQString(i18n("Undock")), this, SLOT(undock()));
mMainMenu->insertItem(TQString(i18n("Close")), this, SLOT(close()));
11 years ago
connect(mMainMenu, SIGNAL(aboutToShow()), this, SLOT(updateMenu()));
// Apply defaults here
setLaunchOnStartup(false);
setDockWhenObscured(false);
enableSessionManagement(true);
mDockWhenMinimized->setOn(isDockWhenMinimized());
mSkipTaskbar->setOn(isSkippingTaskbar());
setAcceptDrops(true); // and you thought this function only installs the menu
}
/*
* Session Management
*/
bool CustomTrayLabel::restoreState(TQSettings& settings)
11 years ago
{
mAutoLaunch->setOn(settings.readBoolEntry("/LaunchOnStartup"));
setDockWhenObscured(settings.readBoolEntry("/DockWhenObscured"));
TRACE("AutoLaunch=%i DWM=%i DWO=%i", isLaunchOnStartup(),
isDockWhenMinimized(), isDockWhenObscured());
return TQTrayLabel::restoreState(settings);
11 years ago
}
bool CustomTrayLabel::saveState(TQSettings& settings)
11 years ago
{
if (!mSessionManagement->isOn()) return false;
TQTrayLabel::saveState(settings);
11 years ago
settings.writeEntry("/LaunchOnStartup", isLaunchOnStartup());
settings.writeEntry("/DockWhenObscured", isDockWhenObscured());
TRACE("AutoLaunch=%i DWM=%i DWO=%i", isLaunchOnStartup(),
isDockWhenMinimized(), isDockWhenObscured());
return true;
}
static bool which(const char *app)
{
if (access(app, X_OK) == 0) return true;
// Check if the program exist in the $PATH
char *path = strdup(getenv("PATH"));
char prog[300];
if (path == NULL) return false;
TRACE("PATH=%s", path);
char *p = strtok(path, ":");
while (p != NULL)
{
snprintf(prog, sizeof(prog), "%s/%s", p, app);
if (access(prog, X_OK) == 0) break;
p = strtok(NULL, ":");
}
free(path);
TRACE("Located at (%s)", p);
return p != NULL;
}
// Overridden to update our menu
void CustomTrayLabel::setDockWhenMinimized(bool dwm)
{
TQTrayLabel::setDockWhenMinimized(dwm);
11 years ago
mDockWhenMinimized->setOn(isDockWhenMinimized());
}
void CustomTrayLabel::setSkipTaskbar(bool skip)
{
TQTrayLabel::setSkipTaskbar(skip);
11 years ago
mSkipTaskbar->setOn(isSkippingTaskbar());
}
void CustomTrayLabel::setAppName(const TQString& name)
11 years ago
{
TQTrayLabel::setAppName(name.lower());
11 years ago
}
/*
* This function is called when TQTrayLabel wants to know whether it can
11 years ago
* unsubscribe from root window. This is because it doesnt know if someone
* else is interested in root window events
*/
bool CustomTrayLabel::canUnsubscribeFromRoot(void)
{
return (TrayLabelMgr::instance())->hiddenLabelsCount() == 0;
}
// Get icon from user, load it and if successful load it.
void CustomTrayLabel::setCustomIcon(void)
{
TQString icon;
11 years ago
while (true)
{
// Nag the user to give us a valid icon or press cancel
icon = TQFileDialog::getOpenFileName();
11 years ago
if (icon.isNull()) return; // user cancelled
if (!TQPixmap(icon).isNull()) break;
11 years ago
TRACE("Attempting to set icon to %s", icon.latin1());
TQMessageBox::critical(this, i18n("TDEDocker"),
i18n("%1 is not a valid icon").arg(icon));
11 years ago
}
setTrayIcon(icon);
}
// Get balloon timeout from the user
void CustomTrayLabel::slotSetBalloonTimeout(void)
{
bool ok;
int timeout = TQInputDialog::getInteger(i18n("TDEDocker"),
i18n("Enter balloon timeout (secs). 0 to disable ballooning"),
11 years ago
balloonTimeout()/1000, 0, 60, 1, &ok);
if (!ok) return;
setBalloonTimeout(timeout * 1000);
}
void CustomTrayLabel::setLaunchOnStartup(bool launch)
{
mAutoLaunch->setOn(launch);
slotSetLaunchOnStartup(); // fake an "activated" signal
}
void CustomTrayLabel::slotSetLaunchOnStartup()
{
TRACE("%i", mAutoLaunch->isOn());
if (!mAutoLaunch->isOn()) return;
TQString app = appName();
11 years ago
TRACE("Validating %s", app.latin1());
while (true)
{
if (which(app.latin1()))
{
TRACE("Autolaunch enabled to %s", app.latin1());
setAppName(app);
mAutoLaunch->setOn(true);
return;
}
// Request user to provide file name himself
if (TQMessageBox::critical(NULL, i18n("TDEDocker"),
i18n("\"%1\" is not a valid executable "
11 years ago
"or was not found in your $PATH").arg(app),
i18n("Select program"), i18n("Cancel")) == 1)
11 years ago
{
mAutoLaunch->setOn(false);
return; // cancelled
}
app = TQFileDialog::getOpenFileName();
11 years ago
if (app.isNull())
{
TRACE("Disabling auto launch");
mAutoLaunch->setOn(false);
return;
}
}
}
// Called when we are just about to display the menu
void CustomTrayLabel::updateMenu(void)
{
TQString title = appClass(); // + "(" + appTitle() + ")";
mMainMenu->changeItem(mShowId, TQIconSet(*pixmap()),
TQString((isWithdrawn() ? i18n("Show %1") : i18n("Hide %1")).arg(title)));
11 years ago
}
void CustomTrayLabel::mapEvent(void)
{
TRACE("mapEvent");
if (mDockWhenObscured->isOn())
{
/*
* We get a obscured event for the time between the map and focus in of
* the window. So we disable it for sometime and reanable.
*/
mDockWhenObscured->setOn(false);
TQTimer::singleShot(800, mDockWhenObscured, SLOT(toggle()));
11 years ago
TRACE("Turning off DWO for some time");
}
}
void CustomTrayLabel::obscureEvent(void)
{
TRACE("obscureEvent");
if (mDockWhenObscured->isOn() && !isWithdrawn())
withdraw();
}
void CustomTrayLabel::focusLostEvent()
{
if (mDockWhenFocusLost->isOn()) withdraw();
}
void CustomTrayLabel::mouseReleaseEvent(TQMouseEvent * ev)
11 years ago
{
if (ev->button() == TQt::RightButton)
11 years ago
mMainMenu->popup(ev->globalPos());
else
toggleShow();
}
void CustomTrayLabel::destroyEvent(void)
{
mUndockWhenDead = true;
TQTrayLabel::destroyEvent();
11 years ago
}
void CustomTrayLabel::processDead(void)
{
/*
* This is a ugly hack but worth every but of ugliness IMO ;).
* Lets say, an instance of xmms, already exists. You type tdedocker xmms.
* TDEDocker launches xmms. xmms cowardly exists seeing its previous instance.
11 years ago
* Wouldnt it be nice now to dock the previous instance of xmms automatically.
* This is more common than you think (think of session restoration)
*/
if (!mUndockWhenDead)
{
scanClients();
if (dockedWindow() != None) return;
}
undock();
}
/*
* Can dock this window iff not docked by another one tray label already
*/
bool CustomTrayLabel::canDockWindow(Window w)
{
TRACE("Checking if 0x%x is already docked", (unsigned) w);
return !(TrayLabelMgr::instance()->isWindowDocked(w));
}
void CustomTrayLabel::dropEvent(TQDropEvent *)
11 years ago
{
TQMessageBox::information(NULL, "TDEDocker",
i18n("You cannot drop an item into the tray icon. Drop it on the window\n"
11 years ago
"that is brought in front when you hover the item over the tray icon"));
}
#include "customtraylabel.moc"