diff options
| author | Slávek Banko <slavek.banko@axis.cz> | 2013-07-05 19:06:59 +0200 | 
|---|---|---|
| committer | Slávek Banko <slavek.banko@axis.cz> | 2013-07-05 19:06:59 +0200 | 
| commit | 14286a0eb6ec163c90e3d13c27fea147dbb82481 (patch) | |
| tree | a5d70bd732b00ec833525dc1d25abc80f2d49144 /src/customtraylabel.cpp | |
| download | tdedocker-14286a0eb6ec163c90e3d13c27fea147dbb82481.tar.gz tdedocker-14286a0eb6ec163c90e3d13c27fea147dbb82481.zip | |
Initial import
Diffstat (limited to 'src/customtraylabel.cpp')
| -rw-r--r-- | src/customtraylabel.cpp | 360 | 
1 files changed, 360 insertions, 0 deletions
| diff --git a/src/customtraylabel.cpp b/src/customtraylabel.cpp new file mode 100644 index 0000000..aca36e1 --- /dev/null +++ b/src/customtraylabel.cpp @@ -0,0 +1,360 @@ +/*  + *  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 <qsettings.h> +#include <qpopupmenu.h> +#include <qmessagebox.h> +#include <qfiledialog.h> +#include <qinputdialog.h> +#include <qaction.h> +#include <qtimer.h> +#include <qsize.h> +#include <stdlib.h> + +#include "trace.h" +#include "customtraylabel.h" +#include "traylabelmgr.h" +#include "kdocker.h" + +CustomTrayLabel::CustomTrayLabel(Window w, QWidget* p, const QString& t) +  : QTrayLabel(w, p, t), mUndockWhenDead(false) +{  +  installMenu();  +} + +CustomTrayLabel::CustomTrayLabel(const QStringList& argv, pid_t pid,  +                                 QWidget* parent) +  : QTrayLabel(argv, pid, parent), mUndockWhenDead(false) +{  +  installMenu();  +} + +/* + * Installs a popup menu on the tray label + */ +void CustomTrayLabel::installMenu() +{ +  QPixmap kdocker_png(QString(ICONS_PATH) + "/kdocker.png"); +  if (kdocker_png.isNull())  +    kdocker_png.load(qApp->applicationDirPath() + "/icons/kdocker.png"); +  setIcon(kdocker_png); +  TrayLabelMgr *tlMgr = TrayLabelMgr::instance(); + +  mOptionsMenu = new QPopupMenu(this); +  mSessionManagement = new QAction(tr("Dock when session restored"), 0, this); +  mSessionManagement->setToggleAction(true); +  connect(mSessionManagement, SIGNAL(toggled(bool)), +          this, SLOT(enableSessionManagement(bool))); +  mSessionManagement->addTo(mOptionsMenu); + +  mAutoLaunch = new QAction(tr("Launch on startup"), 0, this); +	mAutoLaunch->setToggleAction(true); +  connect(mAutoLaunch, SIGNAL(activated()),  +          this, SLOT(slotSetLaunchOnStartup())); +  mAutoLaunch->addTo(mOptionsMenu); + +  mOptionsMenu->insertItem(tr("Set Icon"), this, SLOT(setCustomIcon())); + +  mBalloonTimeout = new QAction(tr("Set balloon timeout"), 0, this); +  connect(mBalloonTimeout, SIGNAL(activated()),  +	        this, SLOT(slotSetBalloonTimeout())); +  mBalloonTimeout->addTo(mOptionsMenu); + +  mDockWhenObscured = new QAction(tr("Dock when obscured"), 0, this); +  mDockWhenObscured->setToggleAction(true); +  connect(mDockWhenObscured, SIGNAL(toggled(bool)), +          this, SLOT(setDockWhenObscured(bool))); +  mDockWhenObscured->addTo(mOptionsMenu); + +  mDockWhenMinimized = new QAction(tr("Dock when minimized"), 0, this); +  mDockWhenMinimized->setToggleAction(true); +  connect(mDockWhenMinimized, SIGNAL(toggled(bool)), +          this, SLOT(setDockWhenMinimized(bool))); +  mDockWhenMinimized->addTo(mOptionsMenu); + +  mDockWhenFocusLost = new QAction(tr("Dock when focus lost"), 0, this); +	mDockWhenFocusLost->setToggleAction(true); +	connect(mDockWhenFocusLost, SIGNAL(toggled(bool)), +					this, SLOT(setDockWhenFocusLost(bool))); +	mDockWhenFocusLost->addTo(mOptionsMenu); + +  mSkipTaskbar = new QAction(tr("Skip taskbar"), 0, this); +  mSkipTaskbar->setToggleAction(true); +  connect(mSkipTaskbar, SIGNAL(toggled(bool)),  +          this, SLOT(setSkipTaskbar(bool))); +  mSkipTaskbar->addTo(mOptionsMenu); + +  mMainMenu = new QPopupMenu(this); +  mMainMenu->insertItem(QIconSet(kdocker_png), +                        tr("About KDocker"), tlMgr, SLOT(about())); +  mMainMenu->insertSeparator(); +  mMainMenu->insertItem(tr("Options"), mOptionsMenu); +  mMainMenu->insertItem(tr("Dock Another"), tlMgr, SLOT(dockAnother())); +  mMainMenu->insertItem(tr("Undock All"), tlMgr, SLOT(undockAll())); +  mMainMenu->insertSeparator(); + +  mShowId = mMainMenu->insertItem(QString("Show/Hide [untitled]"),  +                                  this, SLOT(toggleShow())); +  mMainMenu->insertItem(QString(tr("Undock")), this, SLOT(undock())); +  mMainMenu->insertItem(QString(tr("Close")), this, SLOT(close())); + +  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(QSettings& settings) +{ +  mAutoLaunch->setOn(settings.readBoolEntry("/LaunchOnStartup")); +  setDockWhenObscured(settings.readBoolEntry("/DockWhenObscured")); +  TRACE("AutoLaunch=%i DWM=%i DWO=%i", isLaunchOnStartup(),  +        isDockWhenMinimized(), isDockWhenObscured()); +  return QTrayLabel::restoreState(settings); +} + +bool CustomTrayLabel::saveState(QSettings& settings) +{ +  if (!mSessionManagement->isOn()) return false; +   +  QTrayLabel::saveState(settings); +  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) +{ +  QTrayLabel::setDockWhenMinimized(dwm); +  mDockWhenMinimized->setOn(isDockWhenMinimized()); +} + +void CustomTrayLabel::setSkipTaskbar(bool skip) +{ +  QTrayLabel::setSkipTaskbar(skip); +  mSkipTaskbar->setOn(isSkippingTaskbar()); +} + +void CustomTrayLabel::setAppName(const QString& name) +{ +  QTrayLabel::setAppName(name.lower()); +} + +/* + * This function is called when QTrayLabel 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) +{ +  QString icon; +   +  while (true) +  { +    // Nag the user to give us a valid icon or press cancel +    icon = QFileDialog::getOpenFileName(); +    if (icon.isNull()) return;     // user cancelled +    if (!QPixmap(icon).isNull()) break; +    TRACE("Attempting to set icon to %s", icon.latin1()); +    QMessageBox::critical(this, tr("KDocker"),  +                          tr("%1 is not a valid icon").arg(icon)); +  } +     +  setTrayIcon(icon); +} + +// Get balloon timeout from the user +void CustomTrayLabel::slotSetBalloonTimeout(void) +{ +  bool ok; +  int timeout = QInputDialog::getInteger(tr("KDocker"),  +      tr("Enter balloon timeout (secs). 0 to disable ballooning"),  +			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; +  QString app = appName(); + +  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 (QMessageBox::critical(NULL, tr("KDocker"), +        tr("\"%1\" is not a valid executable " +	  	    "or was not found in your $PATH").arg(app), +        tr("Select program"), tr("Cancel")) == 1)  +    { +      mAutoLaunch->setOn(false); +      return; // cancelled +    } + +    app = QFileDialog::getOpenFileName(); +    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) +{ +  QString title = appClass(); // + "(" + appTitle() + ")"; +  mMainMenu->changeItem(mShowId, QIconSet(*pixmap()), +      QString((isWithdrawn() ? tr("Show %1") : tr("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); +    QTimer::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(QMouseEvent * ev) +{   +  if (ev->button() == Qt::RightButton) +    mMainMenu->popup(ev->globalPos()); +  else +    toggleShow(); +} + +void CustomTrayLabel::destroyEvent(void) +{ +  mUndockWhenDead = true; +  QTrayLabel::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 kdocker xmms. +   * KDocker 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(QDropEvent *) +{ +  QMessageBox::information(NULL, "KDocker",  +    tr("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")); +} + | 
