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.
325 lines
9.7 KiB
325 lines
9.7 KiB
/*
|
|
* 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 <tdepopupmenu.h>
|
|
#include <tqfiledialog.h>
|
|
#include <tqinputdialog.h>
|
|
#include <tqtimer.h>
|
|
#include <stdlib.h>
|
|
|
|
#include <khelpmenu.h>
|
|
#include <kstdaction.h>
|
|
#include <kiconloader.h>
|
|
#include <kstdguiitem.h>
|
|
#include <tdeaction.h>
|
|
#include <tdeconfig.h>
|
|
#include <tdeglobal.h>
|
|
#include <tdelocale.h>
|
|
#include <tdemessagebox.h>
|
|
|
|
#include "trace.h"
|
|
#include "traylabelmgr.h"
|
|
#include "customtraylabel.h"
|
|
|
|
CustomTrayLabel::CustomTrayLabel(Window w, TQWidget* p, const TQString& t)
|
|
: TQTrayLabel(w, p, t), mUndockWhenDead(false)
|
|
{
|
|
installMenu();
|
|
}
|
|
|
|
CustomTrayLabel::CustomTrayLabel(const TQStringList& argv, pid_t pid, TQWidget* parent)
|
|
: TQTrayLabel(argv, pid, parent), mUndockWhenDead(false)
|
|
{
|
|
installMenu();
|
|
}
|
|
|
|
// Installs a popup menu on the tray label
|
|
void CustomTrayLabel::installMenu()
|
|
{
|
|
TQPixmap tdedocker_png(TDEGlobal::iconLoader()->loadIcon("tdedocker", TDEIcon::NoGroup, TDEIcon::SizeSmall));
|
|
setIcon(tdedocker_png);
|
|
TrayLabelMgr *tlMgr = TrayLabelMgr::instance();
|
|
|
|
mOptionsMenu = new TDEPopupMenu(this);
|
|
mSessionManagement = new TQAction(i18n("Dock when session restored"), 0, this);
|
|
mSessionManagement->setToggleAction(true);
|
|
connect(mSessionManagement, SIGNAL(toggled(bool)),
|
|
this, SLOT(enableSessionManagement(bool)));
|
|
mSessionManagement->addTo(mOptionsMenu);
|
|
|
|
mOptionsMenu->insertItem(i18n("Set Icon"), this, SLOT(setCustomIcon()));
|
|
|
|
mBalloonTimeout = new TQAction(i18n("Set balloon timeout"), 0, this);
|
|
connect(mBalloonTimeout, SIGNAL(activated()),
|
|
this, SLOT(slotSetBalloonTimeout()));
|
|
mBalloonTimeout->addTo(mOptionsMenu);
|
|
|
|
mDockWhenObscured = new TQAction(i18n("Dock when obscured"), 0, this);
|
|
mDockWhenObscured->setToggleAction(true);
|
|
connect(mDockWhenObscured, SIGNAL(toggled(bool)),
|
|
this, SLOT(setDockWhenObscured(bool)));
|
|
mDockWhenObscured->addTo(mOptionsMenu);
|
|
|
|
mDockWhenMinimized = new TQAction(i18n("Dock when minimized"), 0, this);
|
|
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);
|
|
mDockWhenFocusLost->setToggleAction(true);
|
|
connect(mDockWhenFocusLost, SIGNAL(toggled(bool)),
|
|
this, SLOT(setDockWhenFocusLost(bool)));
|
|
mDockWhenFocusLost->addTo(mOptionsMenu);
|
|
|
|
mSkipTaskbar = new TQAction(i18n("Skip taskbar"), 0, this);
|
|
mSkipTaskbar->setToggleAction(true);
|
|
connect(mSkipTaskbar, SIGNAL(toggled(bool)),
|
|
this, SLOT(setSkipTaskbar(bool)));
|
|
mSkipTaskbar->addTo(mOptionsMenu);
|
|
|
|
mMainMenu = new TQPopupMenu(this);
|
|
mMainMenu->insertItem(i18n("Options"), mOptionsMenu);
|
|
mMainMenu->insertItem(i18n("Dock Another"), tlMgr, SLOT(dockAnother()));
|
|
mMainMenu->insertItem(i18n("Undock All"), tlMgr, SLOT(undockAll()));
|
|
mMainMenu->insertSeparator();
|
|
|
|
mShowId = mMainMenu->insertItem(TQString("Show/Hide [untitled]"),
|
|
this, SLOT(toggleShow()));
|
|
mMainMenu->insertItem(TQString(i18n("Undock")), this, SLOT(undock()));
|
|
mMainMenu->insertSeparator();
|
|
|
|
mMainMenu->insertItem(SmallIcon("help"),KStdGuiItem::help().text(), (new KHelpMenu(this, TDEGlobal::instance()->aboutData()))->menu(), false);
|
|
TDEAction *quitAction = KStdAction::quit(this, SLOT(close()), NULL);
|
|
quitAction->plug(mMainMenu);
|
|
|
|
connect(mMainMenu, SIGNAL(aboutToShow()), this, SLOT(updateMenu()));
|
|
|
|
// Apply defaults here
|
|
setDockWhenObscured(false);
|
|
enableSessionManagement(true);
|
|
mDockWhenMinimized->setOn(isDockWhenMinimized());
|
|
mSkipTaskbar->setOn(isSkippingTaskbar());
|
|
setAcceptDrops(true); // and you thought this function only installs the menu
|
|
}
|
|
|
|
void CustomTrayLabel::enableSessionManagement(bool sm)
|
|
{
|
|
mSessionManagement->setOn(!appName().isEmpty() && sm);
|
|
}
|
|
|
|
// Session Management
|
|
bool CustomTrayLabel::restoreState(TDEConfig *config)
|
|
{
|
|
setDockWhenObscured(config->readBoolEntry("DockWhenObscured", false));
|
|
TRACE("DWM=%i DWO=%i", isDockWhenMinimized(), isDockWhenObscured());
|
|
return TQTrayLabel::restoreState(config);
|
|
}
|
|
|
|
bool CustomTrayLabel::saveState(TDEConfig *config)
|
|
{
|
|
if (!mSessionManagement->isOn())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (!TQTrayLabel::saveState(config))
|
|
{
|
|
return false;
|
|
}
|
|
config->writeEntry("DockWhenObscured", isDockWhenObscured());
|
|
TRACE("WM=%i DWO=%i", 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);
|
|
mDockWhenMinimized->setOn(isDockWhenMinimized());
|
|
}
|
|
|
|
void CustomTrayLabel::setSkipTaskbar(bool skip)
|
|
{
|
|
TQTrayLabel::setSkipTaskbar(skip);
|
|
mSkipTaskbar->setOn(isSkippingTaskbar());
|
|
}
|
|
|
|
void CustomTrayLabel::setAppName(const TQString& name)
|
|
{
|
|
//FIXME HACK relies on window and application name being the same.
|
|
TQTrayLabel::setAppName(name.lower());
|
|
}
|
|
|
|
/*
|
|
* This function is called when TQTrayLabel wants to know whether it can
|
|
* 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;
|
|
|
|
while (true)
|
|
{
|
|
// Nag the user to give us a valid icon or press cancel
|
|
icon = TQFileDialog::getOpenFileName();
|
|
if (icon.isNull()) return; // user cancelled
|
|
if (!TQPixmap(icon).isNull()) break;
|
|
TRACE("Attempting to set icon to %s", icon.local8Bit());
|
|
KMessageBox::error(this, i18n("%1 is not a valid icon").arg(icon), i18n("TDEDocker"));
|
|
}
|
|
|
|
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"),
|
|
balloonTimeout()/1000, 0, 60, 1, &ok);
|
|
|
|
if (!ok) return;
|
|
setBalloonTimeout(timeout * 1000);
|
|
}
|
|
|
|
// 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)));
|
|
}
|
|
|
|
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()));
|
|
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)
|
|
{
|
|
if (ev->button() == TQt::RightButton)
|
|
{
|
|
mMainMenu->popup(ev->globalPos());
|
|
/* contextMenuAboutToShow(contextMenu());
|
|
contextMenu()->popup(e->globalPos());
|
|
e->accept();
|
|
return;*/
|
|
}
|
|
else
|
|
toggleShow();
|
|
}
|
|
|
|
void CustomTrayLabel::destroyEvent(void)
|
|
{
|
|
mUndockWhenDead = true;
|
|
TQTrayLabel::destroyEvent();
|
|
}
|
|
|
|
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.
|
|
* 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 *)
|
|
{
|
|
KMessageBox::error(NULL, i18n("You cannot drop an item into the tray icon. Drop it on the window\n"
|
|
"that is brought in front when you hover the item over the tray icon"), i18n("TDEDocker"));
|
|
}
|
|
|
|
|
|
#include "customtraylabel.moc"
|