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.
kshutdown/kshutdown/extras.cpp

310 lines
7.2 KiB

/*
extras.cpp - Extras
Copyright (C) 2004 Konrad Twardowski <kdtonline@poczta.onet.pl>
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <sys/types.h>
#include "extras.h"
#include "miscutils.h"
#include "mmainwindow.h"
#include <ntqdir.h>
#include <kdebug.h>
#include <kdesktopfile.h>
#include <kiconloader.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <kmimetype.h>
#include <kpopupmenu.h>
#include <kpushbutton.h>
#include <krun.h>
#include <kstandarddirs.h>
#include <kstringhandler.h>
Extras *Extras::_instance = 0;
// public
Extras::~Extras()
{
if (_idToFileMap)
delete _idToFileMap;
if (_menu)
delete _menu;
}
void Extras::createButton(TQWidget *parent)
{
_button = new KPushButton(parent, "KPushButton::_button");
_button->hide();
_button->setPopup(_menu);
MiscUtils::setHint(_button, i18n("More actions..."));
setAction(TQString::null, TQString::null); /* evil */
}
bool Extras::execAction() const
{
if (_fileToExecute.isNull())
return false; // error
if (!execFile())
{
MiscUtils::showRunErrorMessage(_fileToExecute);
return false; // error
}
return true; // ok
}
TQString Extras::getActionDescription() const
{
return
_description.isEmpty()
? TQString::null
// "Substitute characters at the middle of a string by \"...\""
: KStringHandler::csqueeze(_description, 100);
}
void Extras::setAction(const TQString &fileToExecute, const TQString &description, TQIconSet *icon)
{
_description = description;
_fileToExecute = fileToExecute;
if (_fileToExecute.isNull())
{
_button->setText(i18n("Select a command..."));
_button->setIconSet(ks_actions->getIcon(Action::Extras));
}
else
{
_button->setText(getActionDescription());
if (!icon)
_button->setIconSet(ks_actions->getIcon(Action::Extras));
else
_button->setIconSet(*icon);
}
}
// private
Extras::Extras()
: TQObject(ks_main, "Extras"),
_idToFileMap(0) // initialized in getIdToFileMap()
{
_menu = new KPopupMenu(0, "KPopupMenu::_menu");
connect(_menu, SIGNAL(aboutToShow()), SLOT(slotShowMenu()));
connect(_menu, SIGNAL(activated(int)), SLOT(slotActivated(int)));
}
// TODO: 2.0: recent items
void Extras::buildMenu(KPopupMenu *parentMenu, const TQString &subdir)
{
int id;
TQDir d(subdir);
TQFileInfo fi;
TQString
description,
icon,
mimeType,
name,
path;
TQStringList list = d.entryList(TQDir::DefaultFilter, TQDir::Name | TQDir::DirsFirst);
list.remove(".");
list.remove("..");
uint count = list.count();
for (uint i = 0; i < count; i++)
{
fi.setFile(d, list[i]);
path = fi.filePath();
// dir
if (fi.isDir())
{
KPopupMenu *submenu = new KPopupMenu(parentMenu, "KPopupMenu::submenu");
connect(submenu, SIGNAL(activated(int)), SLOT(slotActivated(int)));
KDesktopFile *desktopFile = new KDesktopFile(path + "/.directory", true);
if (desktopFile->getConfigState() != KConfigBase::NoAccess)
{
icon = desktopFile->readIcon();
if (icon.isEmpty())
icon = "folder";
name = desktopFile->readName();
if (name.isEmpty())
name = fi.baseName();
description = desktopFile->readComment();
// add item
parentMenu->insertItem(
SmallIcon(icon),
description.isEmpty() ? name : description,
submenu
);
}
else
{
// add item
parentMenu->insertItem(SmallIcon("folder"), fi.baseName(), submenu);
}
delete desktopFile;
// recurse
buildMenu(submenu, fi.filePath());
}
// file
else if (fi.isFile())
{
mimeType = KMimeType::findByPath(path)->name();
if (mimeType == "application/x-trash")
continue;
if (mimeType != "application/x-desktop")
{
// add item
id = parentMenu->insertItem(
KMimeType::pixmapForURL(KURL::fromPathOrURL(path)),
fi.baseName()
);
// map item
getIdToFileMap()->insert(id, path);
continue;
}
// application/x-desktop
KDesktopFile *desktopFile = new KDesktopFile(path, true);
if (desktopFile->getConfigState() != KConfigBase::NoAccess)
{
name = desktopFile->readName();
if (name.isEmpty())
name = desktopFile->readEntry("Exec");
description = desktopFile->readComment();
// add item
id = parentMenu->insertItem(
SmallIcon(desktopFile->readIcon()),
description.isEmpty()
? name
: (description + " (" + name + ")")
);
// map item
getIdToFileMap()->insert(id, path);
}
delete desktopFile;
}
}
}
bool Extras::execFile() const
{
if (_fileToExecute.isNull())
{
// kdDebug() << "Extras::execFile(): No file to execute" << endl;
return false;
}
// HACK: It seems that KRun::runURL sometimes does not work for hibernate :/ ?
TQFileInfo fi(_fileToExecute);
if (fi.fileName() == "hibernate.desktop") {
kdDebug() << "Extras::execFile(): Using hacked run..." << endl;
pid_t pid = KRun::runCommand("kfmclient exec \"" + _fileToExecute + "\"");
return pid;
}
else {
pid_t pid = KRun::runURL(
KURL::fromPathOrURL(_fileToExecute),
KMimeType::findByPath(_fileToExecute)->name()
);
return pid;
}
}
TQMap<int, TQString> *Extras::getIdToFileMap()
{
if (!_idToFileMap)
_idToFileMap = new TQMap<int, TQString>;
return _idToFileMap;
}
// public slots
void Extras::slotModify()
{
KMessageBox::information(
0,
MiscUtils::HTML(
i18n("Use context menu to add/edit/remove links.") +
"<ul>" +
"<li>" + i18n("Use <b>Context Menu</b> to create a new link to application") + "</li>" +
"<li>" + i18n("Use <b>Create New|Folder...</b> to create a new submenu") + "</li>" +
"<li>" + i18n("Use <b>Properties</b> to change icon, name, or comment") + "</li>" +
"</ul>"
),
i18n("Extras"), // title
"ModifyExtras" // config key
);
// launch Konqueror as an item editor
MiscUtils::runCommand("konqueror \"" + KGlobal::dirs()->saveLocation("data", "kshutdown/extras") + "\"");
}
// private slots
void Extras::slotActivated(int id)
{
TQMap<int, TQString>::iterator i = getIdToFileMap()->find(id);
if (i == getIdToFileMap()->end())
{
setAction(TQString::null, TQString::null);
KMessageBox::error(
0,
"Internal error!\nSelected menu item is broken.",
i18n("Extras")
);
}
else
{
setAction(i.data(), _menu->text(id), _menu->iconSet(id));
}
}
void Extras::slotShowMenu()
{
setAction(TQString::null, TQString::null);
_menu->clear(); // reset menu
getIdToFileMap()->clear(); // reset map
TQStringList extrasDirs(KGlobal::dirs()->findDirs("data", "kshutdown/extras"));
TQStringList::ConstIterator
begin = extrasDirs.begin(),
end = extrasDirs.end();
for (TQStringList::ConstIterator it = begin; it != end; ++it)
{
if ((it != begin) && (_menu->count() > 0))
_menu->insertSeparator();
buildMenu(_menu, *it);
}
}