summaryrefslogtreecommitdiffstats
path: root/kicker/kicker/ui
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commit4aed2c8219774f5d797760606b8489a92ddc5163 (patch)
tree3f8c130f7d269626bf6a9447407ef6c35954426a /kicker/kicker/ui
downloadtdebase-4aed2c8219774f5d797760606b8489a92ddc5163.tar.gz
tdebase-4aed2c8219774f5d797760606b8489a92ddc5163.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdebase@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kicker/kicker/ui')
-rw-r--r--kicker/kicker/ui/Makefile.am41
-rw-r--r--kicker/kicker/ui/addapplet.cpp542
-rw-r--r--kicker/kicker/ui/addapplet.h82
-rw-r--r--kicker/kicker/ui/addapplet_mnu.cpp75
-rw-r--r--kicker/kicker/ui/addapplet_mnu.h50
-rw-r--r--kicker/kicker/ui/addappletvisualfeedback.cpp230
-rw-r--r--kicker/kicker/ui/addappletvisualfeedback.h80
-rw-r--r--kicker/kicker/ui/addbutton_mnu.cpp73
-rw-r--r--kicker/kicker/ui/addbutton_mnu.h51
-rw-r--r--kicker/kicker/ui/addextension_mnu.cpp58
-rw-r--r--kicker/kicker/ui/addextension_mnu.h47
-rw-r--r--kicker/kicker/ui/appletitem.ui129
-rw-r--r--kicker/kicker/ui/appletop_mnu.cpp208
-rw-r--r--kicker/kicker/ui/appletop_mnu.h55
-rw-r--r--kicker/kicker/ui/appletview.ui204
-rw-r--r--kicker/kicker/ui/appletwidget.h72
-rw-r--r--kicker/kicker/ui/browser_dlg.cpp114
-rw-r--r--kicker/kicker/ui/browser_dlg.h53
-rw-r--r--kicker/kicker/ui/browser_mnu.cpp552
-rw-r--r--kicker/kicker/ui/browser_mnu.h81
-rw-r--r--kicker/kicker/ui/client_mnu.cpp139
-rw-r--r--kicker/kicker/ui/client_mnu.h81
-rw-r--r--kicker/kicker/ui/dirdrop_mnu.cpp39
-rw-r--r--kicker/kicker/ui/dirdrop_mnu.h37
-rw-r--r--kicker/kicker/ui/exe_dlg.cpp204
-rw-r--r--kicker/kicker/ui/exe_dlg.h65
-rw-r--r--kicker/kicker/ui/extensionop_mnu.cpp66
-rw-r--r--kicker/kicker/ui/extensionop_mnu.h36
-rw-r--r--kicker/kicker/ui/hidebutton.cpp202
-rw-r--r--kicker/kicker/ui/hidebutton.h56
-rw-r--r--kicker/kicker/ui/k_mnu.cpp739
-rw-r--r--kicker/kicker/ui/k_mnu.h106
-rw-r--r--kicker/kicker/ui/nonKDEButtonSettings.ui221
-rw-r--r--kicker/kicker/ui/panelmenuiteminfo.h103
-rw-r--r--kicker/kicker/ui/popupmenutitle.cpp33
-rw-r--r--kicker/kicker/ui/popupmenutitle.h85
-rw-r--r--kicker/kicker/ui/quickbrowser_mnu.cpp60
-rw-r--r--kicker/kicker/ui/quickbrowser_mnu.h43
-rw-r--r--kicker/kicker/ui/recentapps.cpp172
-rw-r--r--kicker/kicker/ui/recentapps.h99
-rw-r--r--kicker/kicker/ui/removeapplet_mnu.cpp99
-rw-r--r--kicker/kicker/ui/removeapplet_mnu.h52
-rw-r--r--kicker/kicker/ui/removebutton_mnu.cpp111
-rw-r--r--kicker/kicker/ui/removebutton_mnu.h55
-rw-r--r--kicker/kicker/ui/removecontainer_mnu.cpp61
-rw-r--r--kicker/kicker/ui/removecontainer_mnu.h47
-rw-r--r--kicker/kicker/ui/removeextension_mnu.cpp108
-rw-r--r--kicker/kicker/ui/removeextension_mnu.h48
-rw-r--r--kicker/kicker/ui/service_mnu.cpp823
-rw-r--r--kicker/kicker/ui/service_mnu.h129
50 files changed, 6916 insertions, 0 deletions
diff --git a/kicker/kicker/ui/Makefile.am b/kicker/kicker/ui/Makefile.am
new file mode 100644
index 000000000..e60e99bfd
--- /dev/null
+++ b/kicker/kicker/ui/Makefile.am
@@ -0,0 +1,41 @@
+INCLUDES = -I$(srcdir)/../core -I../core -I$(srcdir)/../buttons \
+ -I../../libkicker -I$(srcdir)/../../libkicker \
+ -I$(top_srcdir)/libkonq -I$(top_srcdir)/kdmlib $(all_includes)
+
+noinst_LTLIBRARIES = libkicker_ui.la
+
+libkicker_ui_la_SOURCES = addbutton_mnu.cpp appletitem.ui appletview.ui addapplet.cpp \
+ addapplet_mnu.cpp appletop_mnu.cpp \
+ browser_mnu.cpp client_mnu.cpp dirdrop_mnu.cpp \
+ nonKDEButtonSettings.ui exe_dlg.cpp k_mnu.cpp k_mnu.skel\
+ quickbrowser_mnu.cpp service_mnu.cpp \
+ addextension_mnu.cpp extensionop_mnu.cpp \
+ recentapps.cpp browser_dlg.cpp \
+ removeapplet_mnu.cpp removeextension_mnu.cpp removecontainer_mnu.cpp \
+ removebutton_mnu.cpp popupmenutitle.cpp hidebutton.cpp \
+ addappletvisualfeedback.cpp
+
+libkicker_ui_la_LIBADD = $(top_builddir)/libkonq/libkonq.la $(top_builddir)/kdmlib/libdmctl.la
+
+libkicker_ui_la_METASOURCES = AUTO
+
+noinst_HEADERS = addapplet.h appletwidget.h addbutton_mnu.h addapplet_mnu.h appletop_mnu.h \
+ browser_mnu.h client_mnu.h dirdrop_mnu.h exe_dlg.h k_mnu.h \
+ quickbrowser_mnu.h service_mnu.h \
+ addextension_mnu.h extensionop_mnu.h \
+ recentapps.h browser_dlg.h \
+ removeapplet_mnu.h removeextension_mnu.h removecontainer_mnu.h \
+ removebutton_mnu.h popupmenutitle.h hidebutton.h addappletvisualfeedback.h
+
+removecontainer_mnu.lo: ../../libkicker/kickerSettings.h
+removeextension_mnu.lo: ../../libkicker/kickerSettings.h
+addextension_mnu.lo: ../core/extensionSettings.h
+appletop_mnu.lo: ../../libkicker/kickerSettings.h
+extensionop_mnu.lo: ../../libkicker/kickerSettings.h
+k_mnu.lo: ../../libkicker/kickerSettings.h
+removecontainer_mnu.lo: ../core/extensionSettings.h
+removeextension_mnu.lo: ../core/extensionSettings.h
+service_mnu.lo: ../../libkicker/kickerSettings.h
+browser_mnu.lo: ../../libkicker/kickerSettings.h
+recentapps.lo: ../../libkicker/kickerSettings.h
+
diff --git a/kicker/kicker/ui/addapplet.cpp b/kicker/kicker/ui/addapplet.cpp
new file mode 100644
index 000000000..e7ac47c9c
--- /dev/null
+++ b/kicker/kicker/ui/addapplet.cpp
@@ -0,0 +1,542 @@
+/*****************************************************************
+
+Copyright (c) 2005 Marc Cramdal
+Copyright (c) 2005 Aaron Seigo <aseigo@kde.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#include <qapplication.h>
+#include <qcombobox.h>
+#include <qdir.h>
+#include <qframe.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qlineedit.h>
+#include <qpalette.h>
+#include <qscrollview.h>
+#include <qtimer.h>
+#include <qsizepolicy.h>
+
+#include <kiconloader.h>
+#include <kdebug.h>
+#include <kglobalsettings.h>
+#include <kpushbutton.h>
+#include <kstandarddirs.h>
+#include <kstdguiitem.h>
+
+#include <paneldrag.h>
+
+#include "addapplet.h"
+#include "addappletvisualfeedback.h"
+#include "appletwidget.h"
+#include "appletview.h"
+#include "container_applet.h"
+#include "container_extension.h"
+#include "containerarea.h"
+#include "kicker.h"
+#include "kickerSettings.h"
+#include "menuinfo.h"
+#include "pluginmanager.h"
+
+AppletWidget::AppletWidget(const AppletInfo& info, bool odd, QWidget *parent)
+ : AppletItem(parent),
+ m_appletInfo(info),
+ m_odd(odd),
+ m_selected(false)
+{
+ setFocusPolicy(QWidget::StrongFocus);
+ setSelected(m_selected);
+
+ itemTitle->setText("<h3>" + info.name() + "</h3>");
+ itemTitle->installEventFilter(this);
+
+ if (info.comment() != info.name())
+ {
+ itemDescription->setText(info.comment());
+ }
+
+ itemDescription->installEventFilter(this);
+
+ KIconLoader * ldr = KGlobal::iconLoader();
+ QPixmap icon = ldr->loadIcon(info.icon(), KIcon::Panel, KIcon::SizeLarge);
+ itemPixmap->setPixmap(icon);
+ itemPixmap->installEventFilter(this);
+}
+
+bool AppletWidget::eventFilter(QObject*, QEvent* e)
+{
+ if (e->type() == QEvent::MouseButtonPress)
+ {
+ QMouseEvent* me = static_cast<QMouseEvent*>(e);
+ if (me->button() & LeftButton)
+ {
+ m_dragStart = me->pos();
+ }
+ }
+ else if (m_dragStart.isNull())
+ {
+ return false;
+ }
+
+ if (e->type() == QEvent::MouseMove)
+ {
+ QMouseEvent* me = static_cast<QMouseEvent*>(e);
+ if ((me->pos() - m_dragStart).manhattanLength() >
+ KGlobalSettings::dndEventDelay())
+ {
+ AppletInfoDrag* drag = new AppletInfoDrag(m_appletInfo, this);
+
+ if (itemPixmap->pixmap())
+ {
+ drag->setPixmap(*itemPixmap->pixmap());
+ }
+
+ drag->dragCopy();
+
+ return true;
+ }
+ }
+ else if (e->type() == QEvent::MouseButtonRelease)
+ {
+ m_dragStart = QPoint();
+ }
+
+ return false;
+}
+
+void AppletWidget::keyPressEvent(QKeyEvent *e)
+{
+ if (e->key() == Qt::Key_Enter ||
+ e->key() == Qt::Key_Return)
+ {
+ emit doubleClicked(this);
+ }
+ else if (e->key() == Qt::Key_Up)
+ {
+ QKeyEvent fakedKeyPress(QEvent::KeyPress, Qt::Key_BackTab, 0, 0);
+ QKeyEvent fakedKeyRelease(QEvent::KeyRelease, Key_BackTab, 0, 0);
+ QApplication::sendEvent(this, &fakedKeyPress);
+ QApplication::sendEvent(this, &fakedKeyRelease);
+ }
+ else if (e->key() == Qt::Key_Down)
+ {
+ QKeyEvent fakedKeyPress(QEvent::KeyPress, Qt::Key_Tab, 0, 0);
+ QKeyEvent fakedKeyRelease(QEvent::KeyRelease, Key_Escape, 0, 0);
+ QApplication::sendEvent(this, &fakedKeyPress);
+ QApplication::sendEvent(this, &fakedKeyRelease);
+ }
+ else
+ {
+ AppletItem::keyPressEvent(e);
+ }
+}
+
+void AppletWidget::mousePressEvent(QMouseEvent *e)
+{
+ if (e->button() == QMouseEvent::LeftButton)
+ {
+ emit clicked(this);
+ m_dragStart = e->pos();
+ }
+
+ setFocus();
+ QWidget::mousePressEvent(e);
+}
+
+void AppletWidget::mouseMoveEvent(QMouseEvent *e)
+{
+ if (e->button() == QMouseEvent::LeftButton &&
+ !m_dragStart.isNull() &&
+ (e->pos() - m_dragStart).manhattanLength() >
+ KGlobalSettings::dndEventDelay())
+ {
+ AppletInfoDrag* drag = new AppletInfoDrag(m_appletInfo, this);
+
+ if (itemPixmap->pixmap())
+ {
+ drag->setPixmap(*itemPixmap->pixmap());
+ }
+
+ drag->dragCopy();
+ }
+}
+
+void AppletWidget::mouseReleaseEvent(QMouseEvent *e)
+{
+ m_dragStart = QPoint();
+ QWidget::mouseReleaseEvent(e);
+}
+
+void AppletWidget::mouseDoubleClickEvent(QMouseEvent *e)
+{
+ if (!e->button() == QMouseEvent::LeftButton)
+ {
+ AppletItem::mouseDoubleClickEvent(e);
+ return;
+ }
+
+ emit doubleClicked(this);
+}
+
+void AppletWidget::setSelected(bool selected)
+{
+ m_selected = selected;
+
+ // for now just used to switch colours around =)
+ if (m_selected)
+ {
+ setPaletteBackgroundColor(KGlobalSettings::highlightColor());
+ setPaletteForegroundColor(KGlobalSettings::highlightedTextColor());
+ }
+ else if (m_odd)
+ {
+ setPaletteBackgroundColor(KGlobalSettings::baseColor());
+ setPaletteForegroundColor(KGlobalSettings::textColor());
+ }
+ else
+ {
+ setPaletteBackgroundColor(KGlobalSettings::alternateBackgroundColor());
+ setPaletteForegroundColor(KGlobalSettings::textColor());
+ }
+}
+
+void AppletWidget::setOdd(bool odd)
+{
+ m_odd = odd;
+ setSelected(m_selected);
+}
+
+void AppletWidget::focusInEvent(QFocusEvent*)
+{
+ emit clicked(this);
+}
+
+AddAppletDialog::AddAppletDialog(ContainerArea* cArea,
+ QWidget* parent,
+ const char* name)
+ : KDialogBase(parent, name, false, i18n("Add Applet"), 0),
+ m_selectedApplet(0),
+ m_containerArea(cArea),
+ m_insertionPoint(Kicker::the()->insertionPoint()),
+ m_closing(false),
+ m_searchDelay(new QTimer(this))
+{
+ m_mainWidget = new AppletView(this, "AddAppletDialog::m_mainWidget");
+ m_mainWidget->appletScrollView->setResizePolicy(QScrollView::Manual);
+ m_mainWidget->appletScrollView->setHScrollBarMode(QScrollView::AlwaysOff);
+ m_mainWidget->appletScrollView->viewport()->setPaletteBackgroundColor(KGlobalSettings::baseColor());
+
+ setMainWidget(m_mainWidget);
+
+ resize(configDialogSize("AddAppletDialog Settings"));
+ centerOnScreen(this);
+
+ KGuiItem addGuiItem = KStdGuiItem::add();
+ addGuiItem.setText(m_mainWidget->appletInstall->text());
+ m_mainWidget->appletInstall->setEnabled(false);
+ m_mainWidget->appletInstall->setGuiItem(addGuiItem);
+ m_mainWidget->closeButton->setGuiItem(KStdGuiItem::close());
+
+ connect(m_mainWidget->appletSearch, SIGNAL(textChanged(const QString&)), this, SLOT(delayedSearch()));
+ connect(m_searchDelay, SIGNAL(timeout()), this, SLOT(search()));
+ connect(m_mainWidget->appletFilter, SIGNAL(activated(int)), this, SLOT(filter(int)));
+ connect(m_mainWidget->appletInstall, SIGNAL(clicked()), this, SLOT(addCurrentApplet()));
+ connect(m_mainWidget->closeButton, SIGNAL(clicked()), this, SLOT(close()));
+
+ m_selectedType = AppletInfo::Undefined;
+ m_appletBox = 0;
+
+ QTimer::singleShot(0, this, SLOT(populateApplets()));
+}
+
+void AddAppletDialog::updateInsertionPoint()
+{
+ m_insertionPoint = Kicker::the()->insertionPoint();
+}
+
+
+void AddAppletDialog::closeEvent(QCloseEvent* e)
+{
+ m_closing = true;
+ saveDialogSize("AddAppletDialog Settings");
+ KDialogBase::closeEvent(e);
+}
+
+void AddAppletDialog::resizeAppletView()
+{
+ int w, h;
+ QScrollView *v = m_mainWidget->appletScrollView;
+
+ if (m_closing)
+ return;
+
+ for (int i = 0; i < 3; i++)
+ {
+ m_appletBox->layout()->activate();
+ w = v->visibleWidth();
+ h = m_appletBox->layout()->minimumSize().height();
+ v->resizeContents(w, QMAX(h, v->visibleHeight()));
+ if (w == m_appletBox->width() && h == m_appletBox->height())
+ break;
+ m_appletBox->resize(w, h);
+ v->updateScrollBars();
+ }
+}
+
+bool AddAppletDialog::eventFilter(QObject *o, QEvent *e)
+{
+ if (e->type() == QEvent::Resize)
+ QTimer::singleShot(0, this, SLOT(resizeAppletView()));
+
+ return QObject::eventFilter(o, e);
+}
+
+void AddAppletDialog::populateApplets()
+{
+ m_appletBox = new QWidget(m_mainWidget->appletScrollView->viewport());
+ m_appletBox->setPaletteBackgroundColor(KGlobalSettings::baseColor());
+ m_mainWidget->appletScrollView->addChild(m_appletBox, 0, 0);
+ m_appletBox->show();
+ QVBoxLayout* layout = new QVBoxLayout(m_appletBox);
+ layout->setMargin(0);
+
+ m_mainWidget->appletScrollView->installEventFilter(this);
+
+ /* Three steps
+ * - First we load the applets
+ * - We load the special buttons
+ * - Then we begin to populate the scrollview with the AppletWidget(s)
+ */
+ AppletInfo::List appletInfoList;
+
+ // Loading applets
+ appletInfoList = PluginManager::applets(false, &appletInfoList);
+
+ // Loading built in buttons
+ appletInfoList = PluginManager::builtinButtons(false, &appletInfoList);
+
+ // Loading special buttons
+ appletInfoList = PluginManager::specialButtons(false, &appletInfoList);
+
+ qHeapSort(appletInfoList);
+
+ int i = 0;
+ bool odd = true;
+ QWidget* prevTabWidget = m_mainWidget->appletFilter;
+
+ for (AppletInfo::List::iterator it = appletInfoList.begin();
+ !m_closing && it != appletInfoList.end();
+ ++i)
+ {
+ if ((*it).isHidden() || (*it).name().isEmpty() ||
+ ((*it).isUniqueApplet() &&
+ PluginManager::the()->hasInstance(*it)))
+ {
+ it = appletInfoList.erase(it);
+ --i;
+ continue;
+ }
+
+ AppletWidget *itemWidget = new AppletWidget(*it, odd, m_appletBox);
+
+ if (m_mainWidget->appletSearch->text().isEmpty() ||
+ appletMatchesSearch(itemWidget, m_mainWidget->appletSearch->text()))
+ {
+ itemWidget->show();
+ odd = !odd;
+ }
+ else
+ {
+ itemWidget->hide();
+ }
+
+ layout->insertWidget(i, itemWidget);
+ m_appletWidgetList.append(itemWidget);
+ setTabOrder(prevTabWidget, itemWidget);
+ prevTabWidget = itemWidget;
+
+ connect(itemWidget, SIGNAL(clicked(AppletWidget*)),
+ this, SLOT(selectApplet(AppletWidget*)));
+ connect(itemWidget, SIGNAL(doubleClicked(AppletWidget*)),
+ this, SLOT(addApplet(AppletWidget*)));
+
+ if (m_closing)
+ {
+ return;
+ }
+
+ ++it;
+ }
+
+ resizeAppletView();
+
+ m_mainWidget->closeButton->setEnabled(true);
+}
+
+void AddAppletDialog::selectApplet(AppletWidget *applet)
+{
+ m_mainWidget->appletInstall->setEnabled(true);
+
+ if (m_selectedApplet)
+ {
+ m_selectedApplet->setSelected(false);
+ }
+
+ m_selectedApplet = applet;
+
+ if (m_selectedApplet)
+ {
+ m_selectedApplet->setSelected(true);
+ }
+}
+
+void AddAppletDialog::addCurrentApplet()
+{
+ addApplet(m_selectedApplet);
+}
+
+void AddAppletDialog::addApplet(AppletWidget* applet)
+{
+ if (!applet)
+ {
+ return;
+ }
+
+ QPoint prevInsertionPoint = Kicker::the()->insertionPoint();
+ Kicker::the()->setInsertionPoint(m_insertionPoint);
+
+ const QWidget* appletContainer = 0;
+
+ if (applet->info().type() == AppletInfo::Applet)
+ {
+ appletContainer = m_containerArea->addApplet(applet->info());
+
+ if (applet->info().isUniqueApplet() &&
+ PluginManager::the()->hasInstance(applet->info()))
+ {
+ applet->hide();
+
+ // reset the odd/even colouring from this item on down in the list
+ bool odd = applet->odd();
+ AppletWidget::List::const_iterator it = m_appletWidgetList.find(applet);
+ for (; it != m_appletWidgetList.constEnd(); ++it)
+ {
+ if ((*it)->isHidden())
+ {
+ continue;
+ }
+
+ (*it)->setOdd(odd);
+ odd = !odd;
+ }
+ }
+ }
+ else if (applet->info().type() & AppletInfo::Button)
+ {
+ appletContainer = m_containerArea->addButton(applet->info());
+ }
+
+ if (appletContainer)
+ {
+ ExtensionContainer* ec =
+ dynamic_cast<ExtensionContainer*>(m_containerArea->topLevelWidget());
+
+ if (ec)
+ {
+ // unhide the panel and keep it unhidden for at least the time the
+ // helper tip will be there
+ ec->unhideIfHidden(KickerSettings::mouseOversSpeed() + 2500);
+ }
+
+ new AddAppletVisualFeedback(applet, appletContainer,
+ m_containerArea->popupDirection());
+ }
+
+ Kicker::the()->setInsertionPoint(prevInsertionPoint);
+}
+
+bool AddAppletDialog::appletMatchesSearch(const AppletWidget* w,
+ const QString& s)
+{
+ if (w->info().type() == AppletInfo::Applet &&
+ w->info().isUniqueApplet() &&
+ PluginManager::the()->hasInstance(w->info()))
+ {
+ return false;
+ }
+
+ return (m_selectedType == AppletInfo::Undefined ||
+ w->info().type() & m_selectedType) &&
+ (w->info().name().contains(s, false) ||
+ w->info().comment().contains(s, false));
+}
+
+void AddAppletDialog::delayedSearch()
+{
+ if (!m_searchDelay->isActive())
+ {
+ m_searchDelay->start(300, true);
+ }
+}
+
+void AddAppletDialog::search()
+{
+ QString s = m_mainWidget->appletSearch->text();
+ bool odd = true;
+ AppletWidget::List::const_iterator it = m_appletWidgetList.constBegin();
+ AppletWidget::List::const_iterator itEnd = m_appletWidgetList.constEnd();
+
+ for (; it != itEnd; ++it)
+ {
+ AppletWidget* w = *it;
+ if (appletMatchesSearch(w, s))
+ {
+ w->setOdd(odd);
+ w->show();
+ odd = !odd;
+ }
+ else
+ {
+ w->hide();
+ }
+ }
+
+ QTimer::singleShot(0, this, SLOT(resizeAppletView()));
+}
+
+void AddAppletDialog::filter(int i)
+{
+ m_selectedType = AppletInfo::Undefined;
+
+ if (i == 1)
+ {
+ m_selectedType = AppletInfo::Applet;
+ }
+ else if (i == 2)
+ {
+ m_selectedType = AppletInfo::Button;
+ }
+
+ search();
+}
+
+#include "addapplet.moc"
+#include "appletwidget.moc"
+
diff --git a/kicker/kicker/ui/addapplet.h b/kicker/kicker/ui/addapplet.h
new file mode 100644
index 000000000..d2ce50a00
--- /dev/null
+++ b/kicker/kicker/ui/addapplet.h
@@ -0,0 +1,82 @@
+/*****************************************************************
+
+Copyright (c) 2005 Marc Cramdal
+Copyright (c) 2005 Aaron Seigo <aseigo@kde.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#ifndef __addapplet_h__
+#define __addapplet_h__
+
+#include <qstringlist.h>
+#include <qpixmap.h>
+#include <qvaluelist.h>
+
+#include <klocale.h>
+#include <kdialogbase.h>
+
+#include "appletinfo.h"
+
+class ContainerArea;
+class AppletView;
+class AppletWidget;
+class QTimer;
+
+class AddAppletDialog : public KDialogBase
+{
+ Q_OBJECT
+
+ public:
+ AddAppletDialog(ContainerArea* cArea, QWidget* parent, const char* name);
+ void updateInsertionPoint();
+
+ protected:
+ void closeEvent(QCloseEvent*);
+ bool eventFilter(QObject *o, QEvent *e);
+
+ private slots:
+ void populateApplets();
+ void addCurrentApplet();
+ void addApplet(AppletWidget* applet);
+ void delayedSearch();
+ void search();
+ void filter(int i);
+ void selectApplet(AppletWidget* applet);
+ void resizeAppletView();
+
+ private:
+ bool appletMatchesSearch(const AppletWidget* w, const QString& s);
+
+ AppletView *m_mainWidget;
+ QWidget *m_appletBox;
+
+ AppletInfo::List m_applets;
+
+ QValueList<AppletWidget*> m_appletWidgetList;
+ AppletWidget* m_selectedApplet;
+
+ ContainerArea* m_containerArea;
+ AppletInfo::AppletType m_selectedType;
+ QPoint m_insertionPoint;
+ bool m_closing;
+ QTimer *m_searchDelay;
+};
+
+#endif
diff --git a/kicker/kicker/ui/addapplet_mnu.cpp b/kicker/kicker/ui/addapplet_mnu.cpp
new file mode 100644
index 000000000..3c3a3db87
--- /dev/null
+++ b/kicker/kicker/ui/addapplet_mnu.cpp
@@ -0,0 +1,75 @@
+/*****************************************************************
+
+Copyright (c) 1996-2000 the kicker authors. See file AUTHORS.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#include <kiconloader.h>
+
+#include "pluginmanager.h"
+#include "containerarea.h"
+
+#include "addapplet_mnu.h"
+#include "addapplet_mnu.moc"
+
+PanelAddAppletMenu::PanelAddAppletMenu(ContainerArea* cArea, QWidget *parent, const char *name)
+ : QPopupMenu(parent, name), containerArea(cArea)
+{
+ setCheckable(true);
+ connect(this, SIGNAL(activated(int)), SLOT(slotExec(int)));
+ connect(this, SIGNAL(aboutToShow()), SLOT(slotAboutToShow()));
+}
+
+void PanelAddAppletMenu::slotAboutToShow()
+{
+ clear();
+
+ applets = PluginManager::applets();
+
+ AppletInfo::List::const_iterator it = applets.constBegin();
+ for (int i = 0; it != applets.constEnd(); ++it, ++i)
+ {
+ const AppletInfo& ai = (*it);
+ if (ai.isHidden())
+ {
+ continue;
+ }
+
+ if (ai.icon().isEmpty() || ai.icon() == "unknown")
+ {
+ insertItem(ai.name().replace( "&", "&&" ), i);
+ }
+ else
+ {
+ insertItem(SmallIconSet(ai.icon()), ai.name().replace( "&", "&&" ), i);
+ }
+
+ if (ai.isUniqueApplet() && PluginManager::the()->hasInstance(ai))
+ {
+ setItemEnabled( i, false );
+ setItemChecked( i, true );
+ }
+ }
+}
+
+void PanelAddAppletMenu::slotExec(int id)
+{
+ containerArea->addApplet( applets[id].desktopFile() );
+}
diff --git a/kicker/kicker/ui/addapplet_mnu.h b/kicker/kicker/ui/addapplet_mnu.h
new file mode 100644
index 000000000..260de26dd
--- /dev/null
+++ b/kicker/kicker/ui/addapplet_mnu.h
@@ -0,0 +1,50 @@
+/*****************************************************************
+
+Copyright (c) 1996-2000 the kicker authors. See file AUTHORS.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#ifndef __addapplet_mnu_h__
+#define __addapplet_mnu_h__
+
+#include <qvaluelist.h>
+#include <qpopupmenu.h>
+
+#include "appletinfo.h"
+
+class ContainerArea;
+
+class PanelAddAppletMenu : public QPopupMenu
+{
+ Q_OBJECT
+
+public:
+ PanelAddAppletMenu(ContainerArea *cArea, QWidget *parent=0, const char *name=0);
+
+protected slots:
+ virtual void slotExec(int id);
+ virtual void slotAboutToShow();
+
+private:
+ AppletInfo::List applets;
+ ContainerArea* containerArea;
+};
+
+#endif
diff --git a/kicker/kicker/ui/addappletvisualfeedback.cpp b/kicker/kicker/ui/addappletvisualfeedback.cpp
new file mode 100644
index 000000000..ce6e618a7
--- /dev/null
+++ b/kicker/kicker/ui/addappletvisualfeedback.cpp
@@ -0,0 +1,230 @@
+/*****************************************************************
+
+Copyright (c) 2004-2005 Aaron J. Seigo <aseigo@kde.org>
+Copyright (c) 2004 Zack Rusin <zrusin@kde.org>
+ Sami Kyostil <skyostil@kempele.fi>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#include <qapplication.h>
+#include <qlabel.h>
+#include <qpainter.h>
+#include <qsimplerichtext.h>
+#include <qtimer.h>
+
+#include <kdialog.h>
+#include <klocale.h>
+
+#include "global.h"
+
+#include "appletinfo.h"
+#include "appletwidget.h"
+#include "addappletvisualfeedback.h"
+#include "kickerSettings.h"
+
+#define DEFAULT_FRAMES_PER_SECOND 30
+
+AddAppletVisualFeedback::AddAppletVisualFeedback(AppletWidget* widget,
+ const QWidget* target,
+ KPanelApplet::Direction direction)
+ : QWidget(0, "animtt", WX11BypassWM),
+ m_target(target),
+ m_direction(direction),
+ m_icon(*widget->itemPixmap->pixmap()),
+ m_richText(0),
+ m_dissolveDelta(-1),
+ m_frames(1),
+ m_dirty(false)
+{
+ setFocusPolicy(NoFocus);
+ setBackgroundMode(NoBackground);
+ connect(&m_moveTimer, SIGNAL(timeout()), SLOT(swoopCloser()));
+
+ QString m = "<qt><h3>" + i18n("%1 Added").arg(widget->info().name());
+
+ if (widget->info().name() != widget->info().comment())
+ {
+ m += "</h3><p>" + widget->info().comment() + "</p></qt>";
+ }
+
+ m_richText = new QSimpleRichText(m, font());
+ m_richText->setWidth(400);
+
+ displayInternal();
+
+ m_destination = KickerLib::popupPosition(m_direction, this, m_target);
+ QPoint startAt = widget->itemPixmap->geometry().topLeft();
+ startAt = widget->itemPixmap->mapToGlobal(startAt);
+ move(startAt);
+
+ m_frames = (m_destination - startAt).manhattanLength() / 20;
+ m_moveTimer.start(10);
+
+ show();
+}
+
+AddAppletVisualFeedback::~AddAppletVisualFeedback()
+{
+ delete m_richText;
+}
+
+void AddAppletVisualFeedback::paintEvent(QPaintEvent * e)
+{
+ if (m_dirty)
+ {
+ displayInternal();
+ m_dirty = false;
+ }
+
+ QPainter p(this);
+ p.drawPixmap(e->rect().topLeft(), m_pixmap, e->rect());
+}
+
+void AddAppletVisualFeedback::mousePressEvent(QMouseEvent *)
+{
+ m_moveTimer.stop();
+ hide();
+ deleteLater();
+}
+
+void AddAppletVisualFeedback::makeMask()
+{
+ QPainter maskPainter(&m_mask);
+
+ m_mask.fill(Qt::black);
+
+ maskPainter.setBrush(Qt::white);
+ maskPainter.setPen(Qt::white);
+ maskPainter.drawRoundRect(m_mask.rect(), 1600 / m_mask.rect().width(),
+ 1600 / m_mask.rect().height());
+ setMask(m_mask);
+}
+
+void AddAppletVisualFeedback::displayInternal()
+{
+ // determine text rectangle
+ QRect textRect(0, 0, 0, 0);
+
+ if (m_frames < 1)
+ {
+ textRect.setWidth(m_richText->widthUsed());
+ textRect.setHeight(m_richText->height());
+ textRect.moveBy(-textRect.left(), -textRect.top());
+ textRect.addCoords(0, 0, 2, 2);
+ }
+
+ int margin = KDialog::marginHint();
+ int height = QMAX(m_icon.height(), textRect.height()) + 2 * margin;
+ int textX = m_icon.isNull() ? margin : 2 + m_icon.width() + 2 * margin;
+ int width = textX;
+
+ if (m_frames < 1)
+ {
+ width += textRect.width() + margin;
+ }
+
+ // resize pixmap, mask and widget
+ m_mask.resize(width, height);
+ m_pixmap.resize(width, height);
+ resize(width, height);
+
+ if (m_frames < 1)
+ {
+ move(KickerLib::popupPosition(m_direction, this, m_target));
+ }
+
+ // create and set transparency mask
+ makeMask();
+
+ // draw background
+ QPainter bufferPainter(&m_pixmap);
+ bufferPainter.setPen(Qt::black);
+ bufferPainter.setBrush(colorGroup().background());
+ bufferPainter.drawRoundRect(0, 0, width, height,
+ 1600 / width, 1600 / height);
+
+ // draw icon if present
+ if (!m_icon.isNull())
+ {
+ bufferPainter.drawPixmap(margin,
+ margin,
+ m_icon, 0, 0,
+ m_icon.width(), m_icon.height());
+ }
+
+ if (m_frames < 1)
+ {
+ int textY = (height - textRect.height()) / 2;
+
+ // draw text shadow
+ QColorGroup cg = colorGroup();
+ cg.setColor(QColorGroup::Text, cg.background().dark(115));
+ int shadowOffset = QApplication::reverseLayout() ? -1 : 1;
+ m_richText->draw(&bufferPainter, 5 + textX + shadowOffset,
+ textY + 1, QRect(), cg);
+
+ // draw text
+ cg = colorGroup();
+ m_richText->draw(&bufferPainter, 5 + textX, textY, rect(), cg);
+ }
+}
+
+void AddAppletVisualFeedback::swoopCloser()
+{
+ if (m_destination.isNull() || m_frames == 0)
+ {
+ return;
+ }
+
+ QPoint loc = geometry().topLeft();
+ bool isLeft = m_destination.x() > loc.x();
+ if (loc.x() != m_destination.x())
+ {
+ int newX = loc.x() + ((m_destination.x() - loc.x()) / m_frames * 2);
+ if ((m_destination.x() > newX) != isLeft)
+ {
+ newX = m_destination.x();
+ }
+ loc.setX(newX);
+ }
+
+ if (loc.y() != m_destination.y())
+ {
+ loc.setY(loc.y() + ((m_destination.y() - loc.y()) / m_frames));
+ }
+
+ move(loc);
+ --m_frames;
+
+ if (m_frames < 1)
+ {
+ m_moveTimer.stop();
+ displayInternal();
+ QTimer::singleShot(2000, this, SLOT(deleteLater()));
+ }
+}
+
+void AddAppletVisualFeedback::internalUpdate()
+{
+ m_dirty = true;
+ repaint(false);
+}
+
+#include "addappletvisualfeedback.moc"
diff --git a/kicker/kicker/ui/addappletvisualfeedback.h b/kicker/kicker/ui/addappletvisualfeedback.h
new file mode 100644
index 000000000..084154704
--- /dev/null
+++ b/kicker/kicker/ui/addappletvisualfeedback.h
@@ -0,0 +1,80 @@
+/*****************************************************************
+
+Copyright (c) 2004-2005 Aaron J. Seigo <aseigo@kde.org>
+Copyright (c) 2004 Zack Rusin <zrusin@kde.org>
+ Sami Kyostil <skyostil@kempele.fi>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#ifndef ADDAPPLETVISUALFEEDBACK_H
+#define ADDAPPLETVISUALFEEDBACK_H
+
+#include <qbitmap.h>
+#include <qpixmap.h>
+#include <qtimer.h>
+#include <qwidget.h>
+
+#include <kpanelapplet.h>
+
+class AppletItem;
+class QPaintEvent;
+class QSimpleRichText;
+class QTimer;
+
+class AddAppletVisualFeedback : QWidget
+{
+ Q_OBJECT
+
+ public:
+ AddAppletVisualFeedback(AppletWidget* parent,
+ const QWidget* destination,
+ KPanelApplet::Direction direction);
+ ~AddAppletVisualFeedback();
+
+ protected slots:
+ void internalUpdate();
+ void swoopCloser();
+
+ protected:
+ void paintEvent(QPaintEvent * e);
+ void mousePressEvent(QMouseEvent * e);
+
+ void makeMask();
+ void displayInternal();
+
+ private:
+ const QWidget* m_target;
+ KPanelApplet::Direction m_direction;
+ QBitmap m_mask;
+ QPixmap m_pixmap;
+ QPixmap m_icon;
+ QSimpleRichText* m_richText;
+
+ int m_dissolveSize;
+ int m_dissolveDelta;
+ int m_frames;
+
+ QTimer m_moveTimer;
+ bool m_dirty;
+
+ QPoint m_destination;
+};
+
+#endif
diff --git a/kicker/kicker/ui/addbutton_mnu.cpp b/kicker/kicker/ui/addbutton_mnu.cpp
new file mode 100644
index 000000000..65a60eea4
--- /dev/null
+++ b/kicker/kicker/ui/addbutton_mnu.cpp
@@ -0,0 +1,73 @@
+/*****************************************************************
+
+Copyright (c) 1996-2000 the kicker authors. See file AUTHORS.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#include <qdragobject.h>
+
+#include <ksycocaentry.h>
+#include <kservice.h>
+#include <kservicegroup.h>
+#include <kstandarddirs.h>
+#include <kdebug.h>
+
+#include "addbutton_mnu.h"
+#include "addbutton_mnu.moc"
+#include "containerarea.h"
+
+PanelAddButtonMenu::PanelAddButtonMenu(ContainerArea* cArea, const QString & label,
+ const QString & relPath, QWidget * parent, const char * name, const QString& _inlineHeader)
+ : PanelServiceMenu(label, relPath, parent, name, true, _inlineHeader), containerArea(cArea)
+{
+}
+
+PanelAddButtonMenu::PanelAddButtonMenu(ContainerArea* cArea, QWidget * parent, const char * name, const QString& _inlineHeader)
+ : PanelServiceMenu(QString::null, QString::null, parent, name, true, _inlineHeader), containerArea(cArea)
+{
+}
+
+void PanelAddButtonMenu::slotExec(int id)
+{
+ if (!entryMap_.contains(id))
+ return;
+
+ KSycocaEntry * e = entryMap_[id];
+
+ if (e->isType(KST_KServiceGroup)) {
+ KServiceGroup::Ptr g = static_cast<KServiceGroup *>(e);
+ containerArea->addServiceMenuButton(g->relPath());
+ } else if (e->isType(KST_KService)) {
+ KService::Ptr service = static_cast<KService *>(e);
+ containerArea->addServiceButton( service->desktopEntryPath() );
+ }
+}
+
+PanelServiceMenu * PanelAddButtonMenu::newSubMenu(const QString & label, const QString & relPath,
+ QWidget * parent, const char * name, const QString& _inlineHeader)
+{
+ return new PanelAddButtonMenu(containerArea, label, relPath, parent, name, _inlineHeader);
+}
+
+void PanelAddButtonMenu::addNonKDEApp()
+{
+ containerArea->addNonKDEAppButton();
+}
+
diff --git a/kicker/kicker/ui/addbutton_mnu.h b/kicker/kicker/ui/addbutton_mnu.h
new file mode 100644
index 000000000..8a9a7e348
--- /dev/null
+++ b/kicker/kicker/ui/addbutton_mnu.h
@@ -0,0 +1,51 @@
+/*****************************************************************
+
+Copyright (c) 1996-2000 the kicker authors. See file AUTHORS.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#ifndef __addbutton_mnu_h__
+#define __addbutton_mnu_h__
+
+#include "service_mnu.h"
+
+class ContainerArea;
+
+class PanelAddButtonMenu : public PanelServiceMenu
+{
+ Q_OBJECT
+
+public:
+ PanelAddButtonMenu(ContainerArea* cArea, const QString & label, const QString & relPath,
+ QWidget * parent = 0, const char * name = 0,const QString& _inlineHeader= QString::null);
+ PanelAddButtonMenu(ContainerArea* cArea, QWidget * parent = 0, const char * name = 0, const QString& _inlineHeader= QString::null);
+
+protected slots:
+ virtual void slotExec(int id);
+ virtual void addNonKDEApp();
+
+protected:
+ virtual PanelServiceMenu * newSubMenu(const QString & label, const QString & relPath,
+ QWidget * parent, const char * name, const QString & _inlineHeader=QString::null);
+private:
+ ContainerArea *containerArea;
+};
+
+#endif
diff --git a/kicker/kicker/ui/addextension_mnu.cpp b/kicker/kicker/ui/addextension_mnu.cpp
new file mode 100644
index 000000000..4ca467f46
--- /dev/null
+++ b/kicker/kicker/ui/addextension_mnu.cpp
@@ -0,0 +1,58 @@
+/*****************************************************************
+
+Copyright (c) 1996-2000 the kicker authors. See file AUTHORS.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#include "extensionmanager.h"
+#include "pluginmanager.h"
+
+#include "addextension_mnu.h"
+#include "addextension_mnu.moc"
+
+PanelAddExtensionMenu::PanelAddExtensionMenu(QWidget *parent, const char *name)
+ : QPopupMenu(parent, name)
+{
+ setCheckable(true);
+ connect(this, SIGNAL(activated(int)), SLOT(slotExec(int)));
+ connect(this, SIGNAL(aboutToShow()), SLOT(slotAboutToShow()));
+}
+
+void PanelAddExtensionMenu::slotAboutToShow()
+{
+ clear();
+
+ extensions = PluginManager::extensions();
+
+ AppletInfo::List::const_iterator it = extensions.constBegin();
+ for( int i = 0; it != extensions.constEnd(); ++it, ++i ) {
+ const AppletInfo& ai = (*it);
+ insertItem( ai.name().replace( "&", "&&" ), i );
+ if ( ai.isUniqueApplet() && PluginManager::the()->hasInstance(ai) ) {
+ setItemEnabled( i, false );
+ setItemChecked( i, true );
+ }
+ }
+}
+
+void PanelAddExtensionMenu::slotExec(int id)
+{
+ ExtensionManager::the()->addExtension( extensions[id].desktopFile() );
+}
diff --git a/kicker/kicker/ui/addextension_mnu.h b/kicker/kicker/ui/addextension_mnu.h
new file mode 100644
index 000000000..60db0c201
--- /dev/null
+++ b/kicker/kicker/ui/addextension_mnu.h
@@ -0,0 +1,47 @@
+/*****************************************************************
+
+Copyright (c) 1996-2000 the kicker authors. See file AUTHORS.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#ifndef __addextension_mnu_h__
+#define __addextension_mnu_h__
+
+#include <qvaluelist.h>
+#include <qpopupmenu.h>
+
+#include "appletinfo.h"
+
+class PanelAddExtensionMenu : public QPopupMenu
+{
+ Q_OBJECT
+
+public:
+ PanelAddExtensionMenu(QWidget *parent=0, const char *name=0);
+
+protected slots:
+ virtual void slotExec(int id);
+ virtual void slotAboutToShow();
+
+private:
+ AppletInfo::List extensions;
+};
+
+#endif
diff --git a/kicker/kicker/ui/appletitem.ui b/kicker/kicker/ui/appletitem.ui
new file mode 100644
index 000000000..d9cc2d9b0
--- /dev/null
+++ b/kicker/kicker/ui/appletitem.ui
@@ -0,0 +1,129 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>AppletItem</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>AppletItem</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>506</width>
+ <height>80</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>32767</width>
+ <height>80</height>
+ </size>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>2</number>
+ </property>
+ <widget class="QLayoutWidget" row="0" column="1">
+ <property name="name">
+ <cstring>layout11</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>itemTitle</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>1</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="textFormat">
+ <enum>RichText</enum>
+ </property>
+ <property name="alignment">
+ <set>WordBreak|AlignTop</set>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>itemDescription</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>1</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="textFormat">
+ <enum>RichText</enum>
+ </property>
+ <property name="alignment">
+ <set>WordBreak|AlignTop</set>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QLayoutWidget" row="0" column="0">
+ <property name="name">
+ <cstring>layout4</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>itemPixmap</cstring>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>64</width>
+ <height>64</height>
+ </size>
+ </property>
+ <property name="margin">
+ <number>4</number>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="alignment">
+ <set>AlignTop</set>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ </grid>
+</widget>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/kicker/kicker/ui/appletop_mnu.cpp b/kicker/kicker/ui/appletop_mnu.cpp
new file mode 100644
index 000000000..435911bbe
--- /dev/null
+++ b/kicker/kicker/ui/appletop_mnu.cpp
@@ -0,0 +1,208 @@
+/*****************************************************************
+
+Copyright (c) 1996-2000 the kicker authors. See file AUTHORS.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#include <klocale.h>
+#include <kiconloader.h>
+#include <kpanelapplet.h>
+#include <kstdguiitem.h>
+
+#include "kicker.h"
+#include "appletop_mnu.h"
+#include "container_button.h"
+#include "containerarea.h"
+
+PanelAppletOpMenu::PanelAppletOpMenu(int actions, QPopupMenu *opMenu, const QPopupMenu* appletsMenu,
+ const QString & title, const QString &icon,
+ QWidget *parent, const char *name)
+ : QPopupMenu(parent, name)
+{
+ bool needSeparator = false;
+ bool isButton = (parent && parent->inherits("ButtonContainer"));
+ bool isMenu = false;
+ QString titleText = title;
+ titleText = titleText.replace('&', "&&");
+ if (isButton)
+ {
+ isMenu = static_cast<ButtonContainer*>(parent)->isAMenu();
+ }
+
+ if (!Kicker::the()->isImmutable())
+ {
+ QString text = isButton ? (isMenu ? i18n("&Move %1 Menu") :
+ i18n("&Move %1 Button")) :
+ i18n("&Move %1");
+ insertItem(SmallIcon("move"), text.arg(titleText), Move);
+
+ // we look for a container area to see if we can add containers
+ // this is part of the kiosk support in kicker, allowing
+ // one to block users from adding new containers
+ ContainerArea* area = 0;
+ QObject* findTheArea = parent ? parent->parent() : 0;
+ while (findTheArea)
+ {
+ area = dynamic_cast<ContainerArea*>(findTheArea);
+
+ if (area)
+ {
+ break;
+ }
+
+ findTheArea = findTheArea->parent();
+ }
+
+ if (!area || area->canAddContainers())
+ {
+ text = isButton ? (isMenu ? i18n("&Remove %1 Menu") :
+ i18n("&Remove %1 Button")) :
+ i18n("&Remove %1");
+ insertItem(SmallIcon("remove"), text.arg(titleText), Remove);
+ needSeparator = true;
+ }
+ }
+
+ if (actions & KPanelApplet::ReportBug)
+ {
+ if (needSeparator)
+ {
+ insertSeparator();
+ needSeparator = false;
+ }
+
+ insertItem(i18n("Report &Bug..."), ReportBug);
+ }
+
+ if (actions & KPanelApplet::About)
+ {
+ if (needSeparator)
+ {
+ insertSeparator();
+ }
+
+ QPixmap iconPix(kapp->iconLoader()->loadIcon(icon,
+ KIcon::Small, 0,
+ KIcon::DefaultState,
+ 0, true));
+ insertItem(iconPix, i18n("&About %1").arg( titleText ), About);
+ needSeparator = !(actions & KPanelApplet::Help);
+ }
+
+ if (actions & KPanelApplet::Help)
+ {
+ if (needSeparator)
+ {
+ insertSeparator();
+ }
+
+ insertItem(SmallIcon("help"), KStdGuiItem::help().text(), Help);
+ needSeparator = true;
+ }
+
+ if (!Kicker::the()->isImmutable() && (actions & KPanelApplet::Preferences))
+ {
+ if (isButton)
+ {
+ insertItem(SmallIcon("configure"),
+ i18n("&Configure %1 Button...").arg(titleText), Preferences);
+ }
+ else
+ {
+ insertItem(SmallIcon("configure"),
+ i18n("&Configure %1...").arg(titleText), Preferences);
+ }
+ needSeparator = true;
+ }
+
+ if (appletsMenu)
+ {
+ if (needSeparator)
+ {
+ insertSeparator();
+ needSeparator = false;
+ }
+
+ QString text = title.isEmpty() ? i18n("Applet Menu") :
+ i18n("%1 Menu").arg(titleText);
+
+ // the 2 const_cast's below prevents const_cast'ing in multiple places
+ // elsewhere in the kicker code base. it's ugly, but unavoidable
+ // unless either QPopupMenu one day allows inserting const
+ // QPopupMenu's or we uglify other bits of kicker's API,
+ // notably KPanelApplet::customMeu()
+ if (icon.isEmpty())
+ {
+ insertItem(text, const_cast<QPopupMenu*>(appletsMenu));
+ }
+ else
+ {
+ insertItem(SmallIcon(icon), text,
+ const_cast<QPopupMenu*>(appletsMenu));
+ }
+ }
+
+ if ((actions & PanelAppletOpMenu::KMenuEditor) && kapp->authorizeKAction("menuedit"))
+ {
+ if (needSeparator)
+ {
+ insertSeparator();
+ needSeparator = false;
+ }
+
+ insertItem(SmallIcon("kmenuedit"), i18n("&Menu Editor"), Preferences);
+ }
+
+ if ((actions & PanelAppletOpMenu::BookmarkEditor) &&
+ kapp->authorizeKAction("edit_bookmarks"))
+ {
+ if (needSeparator)
+ {
+ insertSeparator();
+ }
+ needSeparator = false;
+
+ // NOTE: keditbookmarks is from konqueror. seeing as this is in kdebase
+ // as well this should be ok?
+ insertItem(SmallIcon("keditbookmarks"),
+ i18n("&Edit Bookmarks"),
+ Preferences);
+ }
+
+ if (needSeparator)
+ {
+ insertSeparator();
+ }
+
+ insertItem(SmallIcon("panel"), i18n("Panel Menu"), opMenu);
+ adjustSize();
+}
+
+void PanelAppletOpMenu::keyPressEvent(QKeyEvent* e)
+{
+ if (e->key() == Qt::Key_Escape)
+ {
+ emit escapePressed();
+ }
+
+ QPopupMenu::keyPressEvent(e);
+}
+
+#include "appletop_mnu.moc"
diff --git a/kicker/kicker/ui/appletop_mnu.h b/kicker/kicker/ui/appletop_mnu.h
new file mode 100644
index 000000000..25f03ada6
--- /dev/null
+++ b/kicker/kicker/ui/appletop_mnu.h
@@ -0,0 +1,55 @@
+/*****************************************************************
+
+Copyright (c) 1996-2000 the kicker authors. See file AUTHORS.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#ifndef PANEL_APPLET_OP_MENU_H
+#define PANEL_APPLET_OP_MENU_H
+
+#include <qpopupmenu.h>
+
+class AppletInfo;
+
+// The button operations menu (usually right click)
+class PanelAppletOpMenu : public QPopupMenu
+{
+Q_OBJECT
+
+public:
+ enum OpButton{Move = 9900, Remove = 9901, Help = 9902, About = 9903, Preferences = 9904, ReportBug = 9905 };
+
+ // Note: these entries have to be | and &-able with KPanelApplet::Actions!
+ // they also are treated just like KPanelApplet::Preferences on selection
+ // KDE4: look at merging them there? perhaps under a generic "Editor" option?
+ enum { KMenuEditor = 1048576, BookmarkEditor = 2097152 };
+ PanelAppletOpMenu(int actions, QPopupMenu *opMenu, const QPopupMenu* appletsMenu = 0,
+ const QString &title = 0, const QString &icon = 0,
+ QWidget *parent=0, const char *name=0);
+
+signals:
+ void escapePressed();
+
+protected:
+ void keyPressEvent(QKeyEvent* e);
+};
+
+
+#endif // PANEL_APPLET_OP_MENU_H
diff --git a/kicker/kicker/ui/appletview.ui b/kicker/kicker/ui/appletview.ui
new file mode 100644
index 000000000..a2fa1e91b
--- /dev/null
+++ b/kicker/kicker/ui/appletview.ui
@@ -0,0 +1,204 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>AppletView</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>AppletView</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>490</width>
+ <height>334</height>
+ </rect>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout8</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel8</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Search:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>appletSearch</cstring>
+ </property>
+ </widget>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>appletSearch</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>10</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;qt&gt;Type here some text to filter on the applet names and comments&lt;/qt&gt;</string>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>S&amp;how:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>appletFilter</cstring>
+ </property>
+ </widget>
+ <widget class="QComboBox">
+ <item>
+ <property name="text">
+ <string>All</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Applets</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Special Buttons</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>appletFilter</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>1</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;qt&gt;Select here the only applet category that you want to show&lt;/qt&gt;</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QScrollView">
+ <property name="name">
+ <cstring>appletScrollView</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>1</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>32767</width>
+ <height>32767</height>
+ </size>
+ </property>
+ <property name="focusPolicy">
+ <enum>NoFocus</enum>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;qt&gt;This is the applet list. Select an applet and click on &lt;b&gt;Add to panel&lt;/b&gt; to add it&lt;/qt&gt;</string>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout3</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>spacer8</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>284</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="KPushButton">
+ <property name="name">
+ <cstring>appletInstall</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Add to Panel</string>
+ </property>
+ </widget>
+ <widget class="KPushButton">
+ <property name="name">
+ <cstring>closeButton</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Close</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+</widget>
+<customwidgets>
+ <customwidget>
+ <class>QScrollView</class>
+ <header location="global">qscrollview.h</header>
+ <sizehint>
+ <width>-1</width>
+ <height>-1</height>
+ </sizehint>
+ <container>0</container>
+ <sizepolicy>
+ <hordata>5</hordata>
+ <verdata>5</verdata>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ <pixmap>image0</pixmap>
+ </customwidget>
+</customwidgets>
+<images>
+ <image name="image0">
+ <data format="PNG" length="872">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b0000032f49444154789cb5953148254718c77f1e5b7c030ab3e0c12e5ce00927f88a14af7d87c5590ac29d6013b0497b844008a9120e1248938354a6b1482131cde5a510b4f03081f07c8d4421c2063cd85708bbe0831938613ec8c0a5588dd1dc33452e5f33bb33c36f7ffbed7fd889fe7e9fcb7ad07df09ab750fdfdfec4c425787b6bfb757bae8df79e6a54e1bcc36008845b47e71dc549c1e06000f10a9e5c9a3effee39690ef92cb4a25e2c3b4804709844807035cfd57d7122f0ad65f0c25f0703d4a39af41d28473fa0af4a42548c81f007f85aa86a4510cc34cccc8288420405640ad2bbcadfeb2fb01b39021e7d5513a2c74c59ca43d8db510e0f6a24018d8a2496ecbeb0b892d29d0f08cdbc9d149ac7dc0057bea2831262853196fd5d6573dd43046b85fcbe2002d55019be54bef9a2a45ecd585e059106fe46639318403153427908bd0be8e2a38c874b90e70692806acade4ea0b7eee96d0cc9b2360b8f0d92e835e33b97172106400801b6b73c1a95c54719cbef439a2b9a54f833c3f68f8ec59594f73eb090089b1b153afa67e4ae1b270e5fa7144725d636a6228d853fcf59fbca511e7bdc193cf92467b0eb297f578a2220721d7ccdd82442553b48206f417a1714c5fb94b5cf2b8a638f58a13b9fc2a4a3ddb16854aa53d03806dcf4180481a8d8c98b8f7296b3f6a5a33c6ee2652785fc1ea4d2bcaf248246901bca377a0c661a482cc5505135ecbd088de9a490ddb30c8735cf9e5614872955a96854665a066e4f85a33d0bad96500f95bd9dc0f26a8a3b53ba0f53f20c9e3d85e1cb9a4f3facd0734f9659da1da8ea5b7a0c02a22cae081a95deba676fc7f1e4a39cce7ca0d5097cfc594e9659fca88608dd25cbccdcbfe6384014baf3509f66f436866c7e0d835d4ffb5d0b0954a5c38fb4e92d4af18b521c19ac8c39796ee42ecebe22c0f2aa90656d7adf5714c74a71346c7647b0d39685c7965f7f52aa738fc6947a34c6b83829284a41d2c6441258580a74e7738a22509d36d0bc65687760660e8a25033187c451fec69bc1838301ac0b69de444ad53779c32317bb2481f2d437b9dd6adae13d14874a558f3126c2e0e7cbc59be3b81abf7e67ecca7fac3bd0fca3fe17f0db86f7f7fb137f0208c29bb28f971c5b0000000049454e44ae426082</data>
+ </image>
+</images>
+<tabstops>
+ <tabstop>appletSearch</tabstop>
+ <tabstop>appletFilter</tabstop>
+</tabstops>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>qscrollview.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+</includehints>
+</UI>
diff --git a/kicker/kicker/ui/appletwidget.h b/kicker/kicker/ui/appletwidget.h
new file mode 100644
index 000000000..77d05c2b3
--- /dev/null
+++ b/kicker/kicker/ui/appletwidget.h
@@ -0,0 +1,72 @@
+/*****************************************************************
+
+Copyright (c) 2005 Marc Cramdal
+Copyright (c) 2005 Aaron Seigo <aseigo@kde.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#ifndef _appletwidget_h_
+#define _appletwidget_h_
+
+#include <qpoint.h>
+#include <qvaluelist.h>
+
+#include <klocale.h>
+#include <kdialogbase.h>
+
+#include "appletinfo.h"
+#include "appletitem.h"
+
+class AppletWidget: public AppletItem
+{
+ Q_OBJECT
+
+ public:
+ typedef QValueList<AppletWidget*> List;
+
+ AppletWidget(const AppletInfo& info, bool odd, QWidget *parent);
+ const AppletInfo& info() const { return m_appletInfo; }
+ virtual bool eventFilter(QObject* watched, QEvent* e);
+
+ void setSelected(bool selected);
+ void setOdd(bool odd);
+ bool odd() { return m_odd; }
+
+ signals:
+ void clicked(AppletWidget*);
+ void doubleClicked(AppletWidget*);
+
+ protected:
+ void keyPressEvent(QKeyEvent *e);
+ void mousePressEvent(QMouseEvent *e);
+ void mouseMoveEvent(QMouseEvent *e);
+ void mouseReleaseEvent(QMouseEvent *e);
+ void mouseDoubleClickEvent(QMouseEvent *e);
+ void focusInEvent(QFocusEvent* e);
+
+ private:
+ AppletInfo m_appletInfo;
+ bool m_odd;
+ bool m_selected;
+ QPoint m_dragStart;
+};
+
+#endif
+
diff --git a/kicker/kicker/ui/browser_dlg.cpp b/kicker/kicker/ui/browser_dlg.cpp
new file mode 100644
index 000000000..1fd5d47f6
--- /dev/null
+++ b/kicker/kicker/ui/browser_dlg.cpp
@@ -0,0 +1,114 @@
+/*****************************************************************
+
+Copyright (c) 1996-2000 the kicker authors. See file AUTHORS.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qvbox.h>
+
+#include <kglobal.h>
+#include <klocale.h>
+#include <kicondialog.h>
+#include <kfiledialog.h>
+#include <klineedit.h>
+#include <kmessagebox.h>
+
+#include "browser_dlg.h"
+#include "browser_dlg.moc"
+
+PanelBrowserDialog::PanelBrowserDialog( const QString& path, const QString &icon, QWidget *parent, const char *name )
+ : KDialogBase( parent, name, true, i18n( "Quick Browser Configuration" ), Ok|Cancel, Ok, true )
+{
+ setMinimumWidth( 300 );
+
+ QVBox *page = makeVBoxMainWidget();
+
+ QHBox *hbox2 = new QHBox( page );
+ hbox2->setSpacing( KDialog::spacingHint() );
+ QLabel *label1 = new QLabel( i18n( "Button icon:" ), hbox2 );
+
+ iconBtn = new KIconButton( hbox2 );
+ iconBtn->setFixedSize( 50, 50 );
+ iconBtn->setIconType( KIcon::Panel, KIcon::FileSystem );
+ label1->setBuddy( iconBtn );
+
+ QHBox *hbox1 = new QHBox( page );
+ hbox1->setSpacing( KDialog::spacingHint() );
+ QLabel *label2 = new QLabel( i18n ( "Path:" ), hbox1 );
+ pathInput = new KLineEdit( hbox1 );
+ connect( pathInput, SIGNAL( textChanged ( const QString & )), this, SLOT( slotPathChanged( const QString & )));
+
+ pathInput->setText( path );
+ pathInput->setFocus();
+ label2->setBuddy( pathInput );
+ browseBtn = new QPushButton( i18n( "&Browse..." ), hbox1 );
+ if ( icon.isEmpty() ) {
+ KURL u;
+ u.setPath( path );
+ iconBtn->setIcon( KMimeType::iconForURL( u ) );
+ }
+ else
+ iconBtn->setIcon( icon );
+
+ connect( browseBtn, SIGNAL( clicked() ), this, SLOT( browse() ) );
+}
+
+PanelBrowserDialog::~PanelBrowserDialog()
+{
+
+}
+
+void PanelBrowserDialog::slotPathChanged( const QString &_text )
+{
+ enableButtonOK( !_text.isEmpty() );
+}
+
+void PanelBrowserDialog::browse()
+{
+ QString dir = KFileDialog::getExistingDirectory( pathInput->text(), 0, i18n( "Select Folder" ) );
+ if ( !dir.isEmpty() ) {
+ pathInput->setText( dir );
+ KURL u;
+ u.setPath( dir );
+ iconBtn->setIcon( KMimeType::iconForURL( u ) );
+ }
+}
+
+void PanelBrowserDialog::slotOk()
+{
+ QDir dir(path());
+ if( !dir.exists() ) {
+ KMessageBox::sorry( this, i18n("'%1' is not a valid folder.").arg(path()) );
+ return;
+ }
+ KDialogBase::slotOk();
+}
+
+const QString PanelBrowserDialog::icon()
+{
+ return iconBtn->icon();
+}
+
+QString PanelBrowserDialog::path()
+{
+ return pathInput->text();
+}
diff --git a/kicker/kicker/ui/browser_dlg.h b/kicker/kicker/ui/browser_dlg.h
new file mode 100644
index 000000000..dc675c11c
--- /dev/null
+++ b/kicker/kicker/ui/browser_dlg.h
@@ -0,0 +1,53 @@
+/*****************************************************************
+
+Copyright (c) 1996-2000 the kicker authors. See file AUTHORS.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#ifndef __browser_dlg_h__
+#define __browser_dlg_h__
+
+#include <kdialogbase.h>
+
+class KIconButton;
+class KLineEdit;
+
+class PanelBrowserDialog : public KDialogBase
+{
+ Q_OBJECT
+
+public:
+ PanelBrowserDialog( const QString &path = QString::null, const QString &icon = QString::null, QWidget *parent = 0, const char *name = 0 );
+ ~PanelBrowserDialog();
+
+ const QString icon();
+ QString path();
+
+protected slots:
+ void browse();
+ virtual void slotOk();
+ void slotPathChanged( const QString &_text );
+protected:
+ KIconButton *iconBtn;
+ KLineEdit *pathInput;
+ QPushButton *browseBtn;
+};
+
+#endif
diff --git a/kicker/kicker/ui/browser_mnu.cpp b/kicker/kicker/ui/browser_mnu.cpp
new file mode 100644
index 000000000..9561881eb
--- /dev/null
+++ b/kicker/kicker/ui/browser_mnu.cpp
@@ -0,0 +1,552 @@
+/*****************************************************************
+
+Copyright (c) 2001 Matthias Elter <elter@kde.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#include <qdir.h>
+#include <qpixmap.h>
+
+#include <kapplication.h>
+#include <kdebug.h>
+#include <kdesktopfile.h>
+#include <kdirwatch.h>
+#include <kfileitem.h>
+#include <kglobal.h>
+#include <kglobalsettings.h>
+#include <kiconloader.h>
+#include <kio/global.h>
+#include <klocale.h>
+#include <kmimetype.h>
+#include <konq_operations.h>
+#include <kprocess.h>
+#include <krun.h>
+#include <ksimpleconfig.h>
+#include <kstringhandler.h>
+#include <kurldrag.h>
+
+#include "kickerSettings.h"
+
+#include "browser_mnu.h"
+#include "browser_mnu.moc"
+
+#define CICON(a) (*_icons)[a]
+
+QMap<QString, QPixmap> *PanelBrowserMenu::_icons = 0;
+
+PanelBrowserMenu::PanelBrowserMenu(QString path, QWidget *parent, const char *name, int startid)
+ : KPanelMenu(path, parent, name)
+ , _mimecheckTimer(0)
+ , _startid(startid)
+ , _dirty(false)
+ , _filesOnly(false)
+{
+ _lastpress = QPoint(-1, -1);
+ setAcceptDrops(true); // Should depend on permissions of path.
+
+ // we are not interested for dirty events on files inside the
+ // directory (see slotClearIfNeeded)
+ connect( &_dirWatch, SIGNAL(dirty(const QString&)),
+ this, SLOT(slotClearIfNeeded(const QString&)) );
+ connect( &_dirWatch, SIGNAL(created(const QString&)),
+ this, SLOT(slotClear()) );
+ connect( &_dirWatch, SIGNAL(deleted(const QString&)),
+ this, SLOT(slotClear()) );
+
+ kdDebug() << "PanelBrowserMenu Constructor " << path << endl;
+}
+
+PanelBrowserMenu::~PanelBrowserMenu()
+{
+ kdDebug() << "PanelBrowserMenu Destructor " << path() << endl;
+}
+
+void PanelBrowserMenu::slotClearIfNeeded(const QString& p)
+{
+ if (p == path())
+ slotClear();
+}
+
+void PanelBrowserMenu::initialize()
+{
+ _lastpress = QPoint(-1, -1);
+
+ // don't change menu if already visible
+ if (isVisible())
+ return;
+
+ if (_dirty) {
+ // directory content changed while menu was visible
+ slotClear();
+ setInitialized(false);
+ _dirty = false;
+ }
+
+ if (initialized()) return;
+ setInitialized(true);
+
+ // start watching if not already done
+ if (!_dirWatch.contains(path()))
+ _dirWatch.addDir( path() );
+
+ // setup icon map
+ initIconMap();
+
+ // clear maps
+ _filemap.clear();
+ _mimemap.clear();
+
+ int filter = QDir::Dirs | QDir::Files;
+ if (KickerSettings::showHiddenFiles())
+ {
+ filter |= QDir::Hidden;
+ }
+
+ QDir dir(path(), QString::null, QDir::DirsFirst | QDir::Name | QDir::IgnoreCase, filter);
+
+ // does the directory exist?
+ if (!dir.exists()) {
+ insertItem(i18n("Failed to Read Folder"));
+ return;
+ }
+
+ // get entry list
+ const QFileInfoList *list = dir.entryInfoList();
+
+ // no list -> read error
+ if (!list) {
+ insertItem(i18n("Failed to Read Folder"));
+ return;
+ }
+
+ KURL url;
+ url.setPath(path());
+ if (!kapp->authorizeURLAction("list", KURL(), url))
+ {
+ insertItem(i18n("Not Authorized to Read Folder"));
+ return;
+ }
+
+ // insert file manager and terminal entries
+ // only the first part menu got them
+ if(_startid == 0 && !_filesOnly) {
+ insertTitle(path());
+ insertItem(CICON("kfm"), i18n("Open in File Manager"), this, SLOT(slotOpenFileManager()));
+ if (kapp->authorize("shell_access"))
+ insertItem(CICON("terminal"), i18n("Open in Terminal"), this, SLOT(slotOpenTerminal()));
+ }
+
+
+ bool first_entry = true;
+ bool dirfile_separator = false;
+ unsigned int item_count = 0;
+ int run_id = _startid;
+
+ // get list iterator
+ QFileInfoListIterator it(*list);
+
+ // jump to startid
+ it += _startid;
+
+ // iterate over entry list
+ for (; it.current(); ++it)
+ {
+ // bump id
+ run_id++;
+
+ QFileInfo *fi = it.current();
+ // handle directories
+ if (fi->isDir())
+ {
+ QString name = fi->fileName();
+
+ // ignore . and .. entries
+ if (name == "." || name == "..") continue;
+
+ QPixmap icon;
+ QString path = fi->absFilePath();
+
+ // parse .directory if it does exist
+ if (QFile::exists(path + "/.directory")) {
+
+ KSimpleConfig c(path + "/.directory", true);
+ c.setDesktopGroup();
+ QString iconPath = c.readEntry("Icon");
+
+ if ( iconPath.startsWith("./") )
+ iconPath = path + '/' + iconPath.mid(2);
+
+ icon = KGlobal::iconLoader()->loadIcon(iconPath,
+ KIcon::Small, KIcon::SizeSmall,
+ KIcon::DefaultState, 0, true);
+ if(icon.isNull())
+ icon = CICON("folder");
+ name = c.readEntry("Name", name);
+ }
+
+ // use cached folder icon for directories without special icon
+ if (icon.isNull())
+ icon = CICON("folder");
+
+ // insert separator if we are the first menu entry
+ if(first_entry) {
+ if (_startid == 0 && !_filesOnly)
+ insertSeparator();
+ first_entry = false;
+ }
+
+ // append menu entry
+ PanelBrowserMenu *submenu = new PanelBrowserMenu(path, this);
+ submenu->_filesOnly = _filesOnly;
+ append(icon, name, submenu);
+
+ // bump item count
+ item_count++;
+
+ dirfile_separator = true;
+ }
+ // handle files
+ else if(fi->isFile())
+ {
+ QString name = fi->fileName();
+ QString title = KIO::decodeFileName(name);
+
+ QPixmap icon;
+ QString path = fi->absFilePath();
+
+ bool mimecheck = false;
+
+ // .desktop files
+ if(KDesktopFile::isDesktopFile(path))
+ {
+ KSimpleConfig c(path, true);
+ c.setDesktopGroup();
+ title = c.readEntry("Name", title);
+
+ QString s = c.readEntry("Icon");
+ if(!_icons->contains(s)) {
+ icon = KGlobal::iconLoader()->loadIcon(s, KIcon::Small, KIcon::SizeSmall,
+ KIcon::DefaultState, 0, true);
+
+ if(icon.isNull()) {
+ QString type = c.readEntry("Type", "Application");
+ if (type == "Directory")
+ icon = CICON("folder");
+ else if (type == "Mimetype")
+ icon = CICON("txt");
+ else if (type == "FSDevice")
+ icon = CICON("chardevice");
+ else
+ icon = CICON("exec");
+ }
+ else
+ _icons->insert(s, icon);
+ }
+ else
+ icon = CICON(s);
+ }
+ else {
+ // set unknown icon
+ icon = CICON("unknown");
+
+ // mark for delayed mimetime check
+ mimecheck = true;
+ }
+
+ // insert separator if we are the first menu entry
+ if(first_entry) {
+ if(_startid == 0 && !_filesOnly)
+ insertSeparator();
+ first_entry = false;
+ }
+
+ // insert separator if we we first file after at least one directory
+ if (dirfile_separator) {
+ insertSeparator();
+ dirfile_separator = false;
+ }
+
+ // append file entry
+ append(icon, title, name, mimecheck);
+
+ // bump item count
+ item_count++;
+ }
+
+ if (item_count == KickerSettings::maxEntries2())
+ {
+ // Only insert a "More" item if there are actually more items.
+ ++it;
+ if( it.current() ) {
+ insertSeparator();
+ append(CICON("kdisknav"), i18n("More"), new PanelBrowserMenu(path(), this, 0, run_id));
+ }
+ break;
+ }
+ }
+
+#if 0
+ // WABA: tear off handles don't work together with dynamically updated
+ // menus. We can't update the menu while torn off, and we don't know
+ // when it is torn off.
+ if(KGlobalSettings::insertTearOffHandle() && item_count > 0)
+ insertTearOffHandle();
+#endif
+
+ adjustSize();
+
+ QString dirname = path();
+
+ int maxlen = contentsRect().width() - 40;
+ if(item_count == 0)
+ maxlen = fontMetrics().width(dirname);
+
+ if (fontMetrics().width(dirname) > maxlen) {
+ while ((!dirname.isEmpty()) && (fontMetrics().width(dirname) > (maxlen - fontMetrics().width("..."))))
+ dirname = dirname.remove(0, 1);
+ dirname.prepend("...");
+ }
+ setCaption(dirname);
+
+ // setup and start delayed mimetype check timer
+ if(_mimemap.count() > 0) {
+
+ if(!_mimecheckTimer)
+ _mimecheckTimer = new QTimer(this);
+
+ connect(_mimecheckTimer, SIGNAL(timeout()), SLOT(slotMimeCheck()));
+ _mimecheckTimer->start(0);
+ }
+}
+
+void PanelBrowserMenu::append(const QPixmap &pixmap, const QString &title, const QString &file, bool mimecheck)
+{
+ // avoid &'s being converted to accelerators
+ QString newTitle = title;
+ newTitle = KStringHandler::cEmSqueeze( newTitle, fontMetrics(), 20 );
+ newTitle.replace("&", "&&");
+
+ // insert menu item
+ int id = insertItem(pixmap, newTitle);
+
+ // insert into file map
+ _filemap.insert(id, file);
+
+ // insert into mimetype check map
+ if(mimecheck)
+ _mimemap.insert(id, true);
+}
+
+void PanelBrowserMenu::append(const QPixmap &pixmap, const QString &title, PanelBrowserMenu *subMenu)
+{
+ // avoid &'s being converted to accelerators
+ QString newTitle = title;
+ newTitle = KStringHandler::cEmSqueeze( newTitle, fontMetrics(), 20 );
+ newTitle.replace("&", "&&");
+
+ // insert submenu
+ insertItem(pixmap, newTitle, subMenu);
+ // remember submenu for later deletion
+ _subMenus.append(subMenu);
+}
+
+void PanelBrowserMenu::mousePressEvent(QMouseEvent *e)
+{
+ QPopupMenu::mousePressEvent(e);
+ _lastpress = e->pos();
+}
+
+void PanelBrowserMenu::mouseMoveEvent(QMouseEvent *e)
+{
+ QPopupMenu::mouseMoveEvent(e);
+
+ if (!(e->state() & LeftButton)) return;
+ if(_lastpress == QPoint(-1, -1)) return;
+
+ // DND delay
+ if((_lastpress - e->pos()).manhattanLength() < 12) return;
+
+ // get id
+ int id = idAt(_lastpress);
+ if(!_filemap.contains(id)) return;
+
+ // reset _lastpress
+ _lastpress = QPoint(-1, -1);
+
+ // start drag
+ KURL url;
+ url.setPath(path() + "/" + _filemap[id]);
+ KURL::List files(url);
+ KURLDrag *d = new KURLDrag(files, this);
+ connect(d, SIGNAL(destroyed()), this, SLOT(slotDragObjectDestroyed()));
+ d->setPixmap(iconSet(id)->pixmap());
+ d->drag();
+}
+
+void PanelBrowserMenu::slotDragObjectDestroyed()
+{
+ if (KURLDrag::target() != this)
+ {
+ close();
+ }
+}
+
+void PanelBrowserMenu::dragEnterEvent( QDragEnterEvent *ev )
+{
+ if (KURLDrag::canDecode(ev))
+ {
+ ev->accept();
+ }
+ KPanelMenu::dragEnterEvent(ev);
+}
+
+void PanelBrowserMenu::dragMoveEvent(QDragMoveEvent *ev)
+{
+ QMouseEvent mev(QEvent::MouseMove, ev->pos(), Qt::NoButton, Qt::LeftButton);
+ QPopupMenu::mouseMoveEvent(&mev);
+}
+
+void PanelBrowserMenu::dropEvent( QDropEvent *ev )
+{
+ KURL u( path() );
+ KFileItem item( u, QString::fromLatin1( "inode/directory" ), KFileItem::Unknown );
+ KonqOperations::doDrop( &item, u, ev, this );
+ KPanelMenu::dropEvent(ev);
+ // ### TODO: Update list
+}
+
+void PanelBrowserMenu::slotExec(int id)
+{
+ kapp->propagateSessionManager();
+
+ if(!_filemap.contains(id)) return;
+
+ KURL url;
+ url.setPath(path() + "/" + _filemap[id]);
+ new KRun(url, 0, true); // will delete itself
+ _lastpress = QPoint(-1, -1);
+}
+
+void PanelBrowserMenu::slotOpenTerminal()
+{
+ KConfig * config = kapp->config();
+ config->setGroup("General");
+ QString term = config->readPathEntry("TerminalApplication", "konsole");
+
+ KProcess proc;
+ proc << term;
+ if (term == "konsole")
+ proc << "--workdir" << path();
+ else
+ proc.setWorkingDirectory(path());
+ proc.start(KProcess::DontCare);
+}
+
+void PanelBrowserMenu::slotOpenFileManager()
+{
+ new KRun(path());
+}
+
+void PanelBrowserMenu::slotMimeCheck()
+{
+ // get the first map entry
+ QMap<int, bool>::Iterator it = _mimemap.begin();
+
+ // no mime types left to check -> stop timer
+ if(it == _mimemap.end()) {
+ _mimecheckTimer->stop();
+ delete _mimecheckTimer;
+ _mimecheckTimer = 0;
+ return;
+ }
+
+ int id = it.key();
+ QString file = _filemap[id];
+
+ _mimemap.remove(it);
+
+ KURL url;
+ url.setPath( path() + '/' + file );
+
+// KMimeType::Ptr mt = KMimeType::findByURL(url, 0, true, false);
+// QString icon(mt->icon(url, true));
+ QString icon = KMimeType::iconForURL( url );
+// kdDebug() << url.url() << ": " << icon << endl;
+
+ file = KStringHandler::cEmSqueeze( file, fontMetrics(), 20 );
+ file.replace("&", "&&");
+
+ if(!_icons->contains(icon)) {
+ QPixmap pm = SmallIcon(icon);
+ if( pm.height() > 16 )
+ {
+ QPixmap cropped( 16, 16 );
+ copyBlt( &cropped, 0, 0, &pm, 0, 0, 16, 16 );
+ pm = cropped;
+ }
+ _icons->insert(icon, pm);
+ changeItem(id, pm, file);
+ }
+ else
+ changeItem(id, CICON(icon), file);
+}
+
+void PanelBrowserMenu::slotClear()
+{
+ // no need to watch any further
+ if (_dirWatch.contains(path()))
+ _dirWatch.removeDir( path() );
+
+ // don't change menu if already visible
+ if (isVisible()) {
+ _dirty = true;
+ return;
+ }
+ KPanelMenu::slotClear();
+
+ for (QValueVector<PanelBrowserMenu*>::iterator it = _subMenus.begin();
+ it != _subMenus.end();
+ ++it)
+ {
+ delete *it;
+ }
+ _subMenus.clear(); // deletes submenus
+}
+
+void PanelBrowserMenu::initIconMap()
+{
+ if(_icons) return;
+
+// kdDebug() << "PanelBrowserMenu::initIconMap" << endl;
+
+ _icons = new QMap<QString, QPixmap>;
+
+ _icons->insert("folder", SmallIcon("folder"));
+ _icons->insert("unknown", SmallIcon("mime_empty"));
+ _icons->insert("folder_open", SmallIcon("folder_open"));
+ _icons->insert("kdisknav", SmallIcon("kdisknav"));
+ _icons->insert("kfm", SmallIcon("kfm"));
+ _icons->insert("terminal", SmallIcon("terminal"));
+ _icons->insert("txt", SmallIcon("txt"));
+ _icons->insert("exec", SmallIcon("exec"));
+ _icons->insert("chardevice", SmallIcon("chardevice"));
+}
+
+// vim: sw=4 et
diff --git a/kicker/kicker/ui/browser_mnu.h b/kicker/kicker/ui/browser_mnu.h
new file mode 100644
index 000000000..5999db2cb
--- /dev/null
+++ b/kicker/kicker/ui/browser_mnu.h
@@ -0,0 +1,81 @@
+/*****************************************************************
+
+Copyright (c) 2001 Matthias Elter <elter@kde.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#ifndef __browser_mnu_h__
+#define __browser_mnu_h__
+
+#include <qmap.h>
+#include <qvaluevector.h>
+#include <kpanelmenu.h>
+#include <kdirwatch.h>
+
+class PanelBrowserMenu : public KPanelMenu
+{
+ Q_OBJECT
+
+public:
+ PanelBrowserMenu(QString path, QWidget *parent = 0, const char *name = 0, int startid = 0);
+ ~PanelBrowserMenu();
+
+ void append(const QPixmap &pixmap, const QString &title, const QString &filename, bool mimecheck);
+ void append(const QPixmap &pixmap, const QString &title, PanelBrowserMenu *subMenu);
+
+public slots:
+ void initialize();
+
+protected slots:
+ void slotExec(int id);
+ void slotOpenTerminal();
+ void slotOpenFileManager();
+ void slotMimeCheck();
+ void slotClearIfNeeded(const QString&);
+ void slotClear();
+ void slotDragObjectDestroyed();
+
+protected:
+ void mousePressEvent(QMouseEvent *);
+ void mouseMoveEvent(QMouseEvent *);
+ void dropEvent(QDropEvent *ev);
+ void dragEnterEvent(QDragEnterEvent *ev);
+ void dragMoveEvent(QDragMoveEvent *);
+ void initIconMap();
+
+ QPoint _lastpress;
+ QMap<int, QString> _filemap;
+ QMap<int, bool> _mimemap;
+ QTimer *_mimecheckTimer;
+ KDirWatch _dirWatch;
+ QValueVector<PanelBrowserMenu*> _subMenus;
+
+ int _startid;
+ bool _dirty;
+
+ // With this flag set to 'true' the menu only displays files and
+ // directories. i.e. the "Open in File Manager" and "Open in Terminal"
+ // entries are not inserted in the menu and its submenus.
+ bool _filesOnly;
+
+ static QMap<QString, QPixmap> *_icons;
+};
+
+#endif
diff --git a/kicker/kicker/ui/client_mnu.cpp b/kicker/kicker/ui/client_mnu.cpp
new file mode 100644
index 000000000..f098e40d4
--- /dev/null
+++ b/kicker/kicker/ui/client_mnu.cpp
@@ -0,0 +1,139 @@
+/*****************************************************************
+
+Copyright (c) 1996-2000 the kicker authors. See file AUTHORS.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#include <qpixmap.h>
+
+#include <kapplication.h>
+#include <kdebug.h>
+#include <dcopclient.h>
+
+#include "client_mnu.h"
+#include "client_mnu.moc"
+
+KickerClientMenu::KickerClientMenu( QWidget * parent, const char *name )
+ : QPopupMenu( parent, name), DCOPObject( name )
+{
+}
+
+KickerClientMenu::~KickerClientMenu()
+{
+}
+
+void KickerClientMenu::clear()
+{
+ QPopupMenu::clear();
+}
+
+void KickerClientMenu::insertItem( QPixmap icon, QString text, int id )
+{
+ int globalid = QPopupMenu::insertItem( icon, text, this, SLOT( slotActivated(int) ) );
+ setItemParameter( globalid, id );
+}
+
+void KickerClientMenu::insertItem( QString text, int id )
+{
+ int globalid = QPopupMenu::insertItem( text, this, SLOT( slotActivated(int) ) );
+ setItemParameter( globalid, id );
+}
+
+QCString KickerClientMenu::insertMenu( QPixmap icon, QString text, int id )
+{
+ QString subname("%1-submenu%2");
+ QCString subid = subname.arg(objId()).arg(id).local8Bit();
+ KickerClientMenu *sub = new KickerClientMenu(this, subid);
+ int globalid = QPopupMenu::insertItem( icon, text, sub, id);
+ setItemParameter( globalid, id );
+
+ return subid;
+}
+
+void KickerClientMenu::connectDCOPSignal( QCString signal, QCString appId, QCString objId )
+{
+ // very primitive right now
+ if ( signal == "activated(int)" ) {
+ app = appId;
+ obj = objId;
+ } else {
+ kdWarning() << "DCOP: no such signal " << className() << "::" << signal.data() << endl;
+ }
+}
+
+bool KickerClientMenu::process(const QCString &fun, const QByteArray &data,
+ QCString &replyType, QByteArray &replyData)
+{
+ if ( fun == "clear()" ) {
+ clear();
+ replyType = "void";
+ return true;
+ }
+ else if ( fun == "insertItem(QPixmap,QString,int)" ) {
+ QDataStream dataStream( data, IO_ReadOnly );
+ QPixmap icon;
+ QString text;
+ int id;
+ dataStream >> icon >> text >> id;
+ insertItem( icon, text, id );
+ replyType = "void";
+ return true;
+ }
+ else if ( fun == "insertMenu(QPixmap,QString,int)" ) {
+ QDataStream dataStream( data, IO_ReadOnly );
+ QPixmap icon;
+ QString text;
+ int id;
+ dataStream >> icon >> text >> id;
+ QCString ref = insertMenu( icon, text, id );
+ replyType = "QCString";
+ QDataStream replyStream( replyData, IO_WriteOnly );
+ replyStream << ref;
+ return true;
+ }
+ else if ( fun == "insertItem(QString,int)" ) {
+ QDataStream dataStream( data, IO_ReadOnly );
+ QString text;
+ int id;
+ dataStream >> text >> id;
+ insertItem( text, id );
+ replyType = "void";
+ return true;
+ }
+ else if ( fun == "connectDCOPSignal(QCString,QCString,QCString)" ) {
+ QDataStream dataStream( data, IO_ReadOnly );
+ QCString signal, appId, objId;
+ dataStream >> signal >> appId >> objId;
+ connectDCOPSignal( signal, appId, objId );
+ replyType = "void";
+ return true;
+ }
+ return false;
+}
+
+void KickerClientMenu::slotActivated(int id)
+{
+ if ( !app.isEmpty() ) {
+ QByteArray data;
+ QDataStream dataStream( data, IO_WriteOnly );
+ dataStream << id;
+ kapp->dcopClient()->send( app, obj, "activated(int)", data );
+ }
+}
diff --git a/kicker/kicker/ui/client_mnu.h b/kicker/kicker/ui/client_mnu.h
new file mode 100644
index 000000000..fe8e4a113
--- /dev/null
+++ b/kicker/kicker/ui/client_mnu.h
@@ -0,0 +1,81 @@
+/*****************************************************************
+
+Copyright (c) 1996-2000 the kicker authors. See file AUTHORS.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#ifndef PANEL_CLIENTMENU_H
+#define PANEL_CLIENTMENU_H
+
+#include <qstringlist.h>
+#include <qpopupmenu.h>
+
+#include <dcopobject.h>
+
+
+class PanelKMenu;
+
+// Classes to handle client application menus. Used by PanelKButton, which
+// also manages the toplevel K Button Menu.
+
+/**
+ * Small additions to QPopupMenu to contain data we need for DCop handling
+ */
+class KickerClientMenu : public QPopupMenu, DCOPObject
+{
+ Q_OBJECT
+public:
+ KickerClientMenu( QWidget *parent=0, const char *name=0);
+ ~KickerClientMenu();
+
+ // dcop exported
+ void clear();
+ void insertItem( QPixmap icon, QString text, int id );
+ void insertItem( QString text, int id );
+
+ QCString insertMenu( QPixmap icon, QString test, int id );
+
+ // dcop signals:
+ // void activated(int)
+
+ void connectDCOPSignal( QCString signal, QCString appId, QCString objId );
+
+ // dcop internal
+ virtual bool process(const QCString &fun, const QByteArray &data,
+ QCString &replyType, QByteArray &reply);
+
+protected slots:
+ void slotActivated(int id);
+
+private:
+ QCString app, obj; // for the signal
+
+ // for the panel menu, internal
+ friend class PanelKMenu;
+ QString text;
+ QPixmap icon;
+
+ // for the KickerClientMenu, internal
+ friend class MenuManager;
+ int idInParentMenu;
+ QCString createdBy;
+};
+
+#endif
diff --git a/kicker/kicker/ui/dirdrop_mnu.cpp b/kicker/kicker/ui/dirdrop_mnu.cpp
new file mode 100644
index 000000000..2f64fdd12
--- /dev/null
+++ b/kicker/kicker/ui/dirdrop_mnu.cpp
@@ -0,0 +1,39 @@
+/*****************************************************************
+
+Copyright (c) 1996-2000 the kicker authors. See file AUTHORS.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#include <klocale.h>
+#include <kiconloader.h>
+
+#include "dirdrop_mnu.h"
+
+PanelDirDropMenu::PanelDirDropMenu(QWidget *parent, const char *name)
+ :QPopupMenu(parent, name)
+{
+ insertItem(SmallIconSet("folder"), i18n("Add as &File Manager URL"), Url);
+ setAccel(CTRL+Key_F, Url);
+ insertItem(SmallIconSet("kdisknav"), i18n("Add as Quick&Browser"), Browser);
+ setAccel(CTRL+Key_B, Browser);
+ adjustSize();
+}
+
+
diff --git a/kicker/kicker/ui/dirdrop_mnu.h b/kicker/kicker/ui/dirdrop_mnu.h
new file mode 100644
index 000000000..15fa799c2
--- /dev/null
+++ b/kicker/kicker/ui/dirdrop_mnu.h
@@ -0,0 +1,37 @@
+/*****************************************************************
+
+Copyright (c) 1996-2000 the kicker authors. See file AUTHORS.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#ifndef __dirdrop_mnu_h__
+#define __dirdrop_mnu_h__
+
+#include <qpopupmenu.h>
+
+// The directory dropped menu
+class PanelDirDropMenu : public QPopupMenu
+{
+public:
+ enum OpButton{Url=1, Browser};
+ PanelDirDropMenu(QWidget *parent=0, const char *name=0);
+};
+
+#endif
diff --git a/kicker/kicker/ui/exe_dlg.cpp b/kicker/kicker/ui/exe_dlg.cpp
new file mode 100644
index 000000000..19583444e
--- /dev/null
+++ b/kicker/kicker/ui/exe_dlg.cpp
@@ -0,0 +1,204 @@
+/*****************************************************************
+
+Copyright (c) 1996-2000 the kicker authors. See file AUTHORS.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#include <qfileinfo.h>
+
+#include <klocale.h>
+#include <kiconloader.h>
+
+#include <qcheckbox.h>
+#include <qdir.h>
+#include <qfileinfo.h>
+#include <qlineedit.h>
+#include <qvbox.h>
+
+#include <kicondialog.h>
+#include <kmessagebox.h>
+#include <kmimetype.h>
+#include <kstandarddirs.h>
+#include <kurlcompletion.h>
+#include <kurlrequester.h>
+#include <kurl.h>
+
+#include <kdebug.h>
+
+#include "exe_dlg.h"
+#include "nonKDEButtonSettings.h"
+
+PanelExeDialog::PanelExeDialog(const QString& title, const QString& description,
+ const QString &path, const QString &icon,
+ const QString &cmd, bool inTerm,
+ QWidget *parent, const char *name)
+ : KDialogBase(parent, name, false, i18n("Non-KDE Application Configuration"), Ok|Cancel, Ok, true),
+ m_icon(icon.isEmpty() ? "exec" : icon),
+ m_iconChanged(false)
+{
+ setCaption(i18n("Non-KDE Application Configuration"));
+ QFileInfo fi(path);
+
+ ui = new NonKDEButtonSettings(makeVBoxMainWidget());
+ fillCompletion();
+
+ ui->m_title->setText(title);
+ ui->m_description->setText(description);
+ ui->m_exec->setURL(path);
+ ui->m_commandLine->setText(cmd);
+ ui->m_inTerm->setChecked(inTerm);
+ ui->m_icon->setIconType(KIcon::Panel, KIcon::Application);
+
+ updateIcon();
+
+ connect(ui->m_exec, SIGNAL(urlSelected(const QString &)),
+ this, SLOT(slotSelect(const QString &)));
+ connect(ui->m_exec, SIGNAL(textChanged(const QString &)),
+ this, SLOT(slotTextChanged(const QString &)));
+ connect(ui->m_exec, SIGNAL(returnPressed()),
+ this, SLOT(slotReturnPressed()));
+ connect(ui->m_icon, SIGNAL(iconChanged(QString)),
+ this, SLOT(slotIconChanged(QString)));
+
+ // leave decent space for the commandline
+ resize(sizeHint().width() > 300 ? sizeHint().width() : 300,
+ sizeHint().height());
+}
+
+void PanelExeDialog::slotOk()
+{
+ KDialogBase::slotOk();
+ // WARNING! we get delete after this, so don't do anything after it!
+ emit updateSettings(this);
+}
+
+bool PanelExeDialog::useTerminal() const
+{
+ return ui->m_inTerm->isChecked();
+}
+
+QString PanelExeDialog::title() const
+{
+ return ui->m_title->text();
+}
+
+QString PanelExeDialog::description() const
+{
+ return ui->m_description->text();
+}
+
+QString PanelExeDialog::commandLine() const
+{
+ return ui->m_commandLine->text();
+}
+
+QString PanelExeDialog::iconPath() const
+{
+ return ui->m_icon->icon();
+}
+
+QString PanelExeDialog::command() const
+{
+ return ui->m_exec->url();
+}
+
+void PanelExeDialog::updateIcon()
+{
+ if(!m_icon.isEmpty())
+ ui->m_icon->setIcon(m_icon);
+}
+
+void PanelExeDialog::fillCompletion()
+{
+ KCompletion *comp = ui->m_exec->completionObject();
+ QStringList exePaths = KStandardDirs::systemPaths();
+
+ for (QStringList::ConstIterator it = exePaths.begin(); it != exePaths.end(); it++)
+ {
+ QDir d( (*it) );
+ d.setFilter( QDir::Files | QDir::Executable );
+
+ const QFileInfoList *list = d.entryInfoList();
+ if (!list)
+ continue;
+
+ QFileInfoListIterator it2( *list );
+ QFileInfo *fi;
+
+ while ( (fi = it2.current()) != 0 ) {
+ m_partialPath2full.insert(fi->fileName(), fi->filePath(), false);
+ comp->addItem(fi->fileName());
+ comp->addItem(fi->filePath());
+ ++it2;
+ }
+ }
+}
+
+void PanelExeDialog::slotIconChanged(QString)
+{
+ m_iconChanged = true;
+}
+
+void PanelExeDialog::slotTextChanged(const QString &str)
+{
+ if (m_iconChanged)
+ {
+ return;
+ }
+
+ QString exeLocation = str;
+ QMap<QString, QString>::iterator it = m_partialPath2full.find(str);
+
+ if (it != m_partialPath2full.end())
+ exeLocation = it.data();
+ KMimeType::pixmapForURL(KURL( exeLocation ), 0, KIcon::Panel, 0, KIcon::DefaultState, &m_icon);
+ updateIcon();
+}
+
+void PanelExeDialog::slotReturnPressed()
+{
+ if (m_partialPath2full.contains(ui->m_exec->url()))
+ ui->m_exec->setURL(m_partialPath2full[ui->m_exec->url()]);
+}
+
+void PanelExeDialog::slotSelect(const QString& exec)
+{
+ if ( exec.isEmpty() )
+ return;
+
+ QFileInfo fi(exec);
+ if (!fi.isExecutable())
+ {
+ if(KMessageBox::warningYesNo(0, i18n("The selected file is not executable.\n"
+ "Do you want to select another file?"), i18n("Not Executable"), i18n("Select Other"), KStdGuiItem::cancel())
+ == KMessageBox::Yes)
+ {
+ ui->m_exec->button()->animateClick();
+ }
+
+ return;
+ }
+
+ KMimeType::pixmapForURL(KURL( exec ), 0, KIcon::Panel, 0, KIcon::DefaultState, &m_icon);
+ updateIcon();
+}
+
+#include "exe_dlg.moc"
+
diff --git a/kicker/kicker/ui/exe_dlg.h b/kicker/kicker/ui/exe_dlg.h
new file mode 100644
index 000000000..f7624fa35
--- /dev/null
+++ b/kicker/kicker/ui/exe_dlg.h
@@ -0,0 +1,65 @@
+/*****************************************************************
+
+Copyright (c) 1996-2000 the kicker authors. See file AUTHORS.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#ifndef __exe_dlg_h__
+#define __exe_dlg_h__
+
+#include <kdialogbase.h>
+class NonKDEButtonSettings;
+
+class PanelExeDialog : public KDialogBase
+{
+ Q_OBJECT
+public:
+ PanelExeDialog(const QString& title, const QString& description,
+ const QString &path, const QString &pixmap=QString::null,
+ const QString &cmd=QString::null, bool inTerm=false,
+ QWidget *parent=0, const char *name=0);
+ QString iconPath() const;
+ QString command() const;
+ QString commandLine() const;
+ QString title() const;
+ QString description() const;
+ bool useTerminal() const;
+
+signals:
+ void updateSettings(PanelExeDialog*);
+
+protected slots:
+ void slotSelect(const QString& exec);
+ void slotTextChanged(const QString &);
+ void slotReturnPressed();
+ void slotIconChanged(QString);
+ void slotOk();
+
+protected:
+ void fillCompletion();
+ void updateIcon();
+
+ NonKDEButtonSettings* ui;
+ QString m_icon;
+ QMap<QString, QString> m_partialPath2full;
+ bool m_iconChanged;
+};
+
+#endif
diff --git a/kicker/kicker/ui/extensionop_mnu.cpp b/kicker/kicker/ui/extensionop_mnu.cpp
new file mode 100644
index 000000000..9389f9cd4
--- /dev/null
+++ b/kicker/kicker/ui/extensionop_mnu.cpp
@@ -0,0 +1,66 @@
+/*****************************************************************
+
+Copyright (c) 1996-2000 the kicker authors. See file AUTHORS.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#include <klocale.h>
+#include <kiconloader.h>
+#include <kpanelextension.h>
+#include <kstdguiitem.h>
+
+#include "kicker.h"
+#include "extensionop_mnu.h"
+
+PanelExtensionOpMenu::PanelExtensionOpMenu(const QString& extension, int actions, QWidget *parent, const char *name)
+ : QPopupMenu(parent, name)
+{
+ if (!Kicker::the()->isImmutable())
+ {
+ insertItem(SmallIcon("remove"), i18n("&Remove"), Remove);
+ }
+
+ if (actions & KPanelExtension::ReportBug)
+ {
+ insertSeparator();
+ insertItem(i18n("Report &Bug..."), ReportBug);
+ }
+
+ if (actions & KPanelExtension::Help
+ || actions & KPanelExtension::About)
+ insertSeparator();
+
+ if (actions & KPanelExtension::About)
+ {
+ insertItem(i18n("&About"), About);
+ }
+
+ if (actions & KPanelExtension::Help)
+ {
+ insertItem(SmallIcon("help"), KStdGuiItem::help().text(), Help);
+ }
+
+ if (!Kicker::the()->isImmutable() && (actions & KPanelExtension::Preferences)) {
+ insertSeparator();
+ insertItem(SmallIcon("configure"), i18n("&Configure %1...").arg(extension), Preferences);
+ }
+
+ adjustSize();
+}
diff --git a/kicker/kicker/ui/extensionop_mnu.h b/kicker/kicker/ui/extensionop_mnu.h
new file mode 100644
index 000000000..85bf914af
--- /dev/null
+++ b/kicker/kicker/ui/extensionop_mnu.h
@@ -0,0 +1,36 @@
+/*****************************************************************
+
+Copyright (c) 1996-2000 the kicker authors. See file AUTHORS.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#ifndef __extensionop_mnu_h__
+#define __extensionop_mnu_h__
+
+#include <qpopupmenu.h>
+
+class PanelExtensionOpMenu : public QPopupMenu
+{
+public:
+ enum OpButton{Move = 9900, Remove = 9901, Help = 9902, About = 9903, Preferences = 9904, ReportBug = 9905, Shade = 9906 };
+ PanelExtensionOpMenu(const QString& extension, int actions, QWidget *parent=0, const char *name=0);
+};
+
+#endif
diff --git a/kicker/kicker/ui/hidebutton.cpp b/kicker/kicker/ui/hidebutton.cpp
new file mode 100644
index 000000000..31d614006
--- /dev/null
+++ b/kicker/kicker/ui/hidebutton.cpp
@@ -0,0 +1,202 @@
+/* This file is part of the KDE project
+ Copyright (C) 2003-2004 Nadeem Hasan <nhasan@kde.org>
+ Copyright (C) 2004 Aaron J. Seigo <aseigo@kde.org>
+
+ 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; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "hidebutton.h"
+
+#include <qpainter.h>
+
+#include <kapplication.h>
+#include <kcursor.h>
+#include <kglobalsettings.h>
+#include <kiconeffect.h>
+#include <kiconloader.h>
+#include <kicontheme.h>
+#include <kipc.h>
+#include <kstandarddirs.h>
+
+HideButton::HideButton(QWidget *parent, const char *name)
+ : QButton(parent, name),
+ m_highlight(false),
+ m_arrow(Qt::LeftArrow)
+{
+ setBackgroundOrigin(AncestorOrigin);
+
+ connect(kapp, SIGNAL(settingsChanged(int)), SLOT(slotSettingsChanged(int)));
+ connect(kapp, SIGNAL(iconChanged(int)), SLOT(slotIconChanged(int)));
+
+ kapp->addKipcEventMask(KIPC::SettingsChanged);
+ kapp->addKipcEventMask(KIPC::IconChanged);
+
+ slotSettingsChanged(KApplication::SETTINGS_MOUSE);
+}
+
+void HideButton::drawButton(QPainter *p)
+{
+ if (m_arrow == Qt::LeftArrow)
+ {
+ p->setPen(colorGroup().mid());
+ p->drawLine(width()-1, 0, width()-1, height());
+ }
+ else if (m_arrow == Qt::RightArrow)
+ {
+ p->setPen(colorGroup().mid());
+ p->drawLine(0, 0, 0, height());
+ }
+ else if (m_arrow == Qt::UpArrow)
+ {
+ p->setPen(colorGroup().mid());
+ p->drawLine(0, height()-1, width(), height()-1);
+ }
+ else if (m_arrow == Qt::DownArrow)
+ {
+ p->setPen(colorGroup().mid());
+ p->drawLine(0, 0, width(), 0);
+ }
+
+ drawButtonLabel(p);
+}
+
+void HideButton::drawButtonLabel(QPainter *p)
+{
+ if (pixmap())
+ {
+ QPixmap pix = m_highlight? m_activeIcon : m_normalIcon;
+
+ if (isOn() || isDown())
+ {
+ p->translate(2, 2);
+ }
+
+ QPoint origin(2, 2);
+
+ if (pix.height() < (height() - 4))
+ {
+ origin.setY(origin.y() + ((height() - pix.height()) / 2));
+ }
+
+ if (pix.width() < (width() - 4))
+ {
+ origin.setX(origin.x() + ((width() - pix.width()) / 2));
+ }
+
+ p->drawPixmap(origin, pix);
+ }
+}
+
+void HideButton::setPixmap(const QPixmap &pix)
+{
+ QButton::setPixmap(pix);
+ generateIcons();
+}
+
+void HideButton::setArrowType(Qt::ArrowType arrow)
+{
+ m_arrow = arrow;
+ switch (arrow)
+ {
+ case Qt::LeftArrow:
+ setPixmap(SmallIcon("1leftarrow"));
+ break;
+
+ case Qt::RightArrow:
+ setPixmap(SmallIcon("1rightarrow"));
+ break;
+
+ case Qt::UpArrow:
+ setPixmap(SmallIcon("1uparrow"));
+ break;
+
+ case Qt::DownArrow:
+ default:
+ setPixmap(SmallIcon("1downarrow"));
+ break;
+ }
+}
+
+void HideButton::generateIcons()
+{
+ if (!pixmap())
+ {
+ return;
+ }
+
+ QImage image = pixmap()->convertToImage();
+ image = image.smoothScale(size() - QSize(4, 4), QImage::ScaleMin);
+
+ KIconEffect effect;
+
+ m_normalIcon = effect.apply(image, KIcon::Panel, KIcon::DefaultState);
+ m_activeIcon = effect.apply(image, KIcon::Panel, KIcon::ActiveState);
+}
+
+void HideButton::slotSettingsChanged(int category)
+{
+ if (category != KApplication::SETTINGS_MOUSE)
+ {
+ return;
+ }
+
+ bool changeCursor = KGlobalSettings::changeCursorOverIcon();
+
+ if (changeCursor)
+ {
+ setCursor(KCursor::handCursor());
+ }
+ else
+ {
+ unsetCursor();
+ }
+}
+
+void HideButton::slotIconChanged(int group)
+{
+ if (group != KIcon::Panel)
+ {
+ return;
+ }
+
+ generateIcons();
+ repaint(false);
+}
+
+void HideButton::enterEvent(QEvent *e)
+{
+ m_highlight = true;
+
+ repaint(false);
+ QButton::enterEvent(e);
+}
+
+void HideButton::leaveEvent(QEvent *e)
+{
+ m_highlight = false;
+
+ repaint(false);
+ QButton::enterEvent(e);
+}
+
+void HideButton::resizeEvent(QResizeEvent *)
+{
+ generateIcons();
+}
+
+#include "hidebutton.moc"
+
+// vim:ts=4:sw=4:et
diff --git a/kicker/kicker/ui/hidebutton.h b/kicker/kicker/ui/hidebutton.h
new file mode 100644
index 000000000..da387cde7
--- /dev/null
+++ b/kicker/kicker/ui/hidebutton.h
@@ -0,0 +1,56 @@
+/* This file is part of the KDE project
+ Copyright (C) 2003-2004 Nadeem Hasan <nhasan@kde.org>
+
+ 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; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef HIDEBUTTON_H
+#define HIDEBUTTON_H
+
+#include <qbutton.h>
+#include <qpixmap.h>
+
+class HideButton : public QButton
+{
+ Q_OBJECT
+
+ public:
+ HideButton(QWidget *parent, const char *name = 0);
+ void setArrowType(Qt::ArrowType arrow);
+ void setPixmap(const QPixmap &pix);
+
+ protected:
+ void drawButton(QPainter *p);
+ void drawButtonLabel(QPainter *p);
+ void generateIcons();
+
+ void enterEvent(QEvent *e);
+ void leaveEvent( QEvent *e );
+ void resizeEvent(QResizeEvent *e);
+
+ bool m_highlight;
+ QPixmap m_normalIcon;
+ QPixmap m_activeIcon;
+ Qt::ArrowType m_arrow;
+
+ protected slots:
+ void slotSettingsChanged( int category );
+ void slotIconChanged( int group );
+};
+
+#endif // HIDEBUTTON_H
+
+// vim:ts=4:sw=4:et
diff --git a/kicker/kicker/ui/k_mnu.cpp b/kicker/kicker/ui/k_mnu.cpp
new file mode 100644
index 000000000..609ce84be
--- /dev/null
+++ b/kicker/kicker/ui/k_mnu.cpp
@@ -0,0 +1,739 @@
+/*****************************************************************
+
+Copyright (c) 1996-2000 the kicker authors. See file AUTHORS.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#include <stdlib.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <dmctl.h>
+
+#include <qimage.h>
+#include <qpainter.h>
+#include <qstyle.h>
+
+#include <dcopclient.h>
+#include <kapplication.h>
+#include <kaboutkde.h>
+#include <kaction.h>
+#include <kbookmarkmenu.h>
+#include <kconfig.h>
+#include <kdebug.h>
+#include <kglobal.h>
+#include <kglobalsettings.h>
+#include <kiconloader.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kstandarddirs.h>
+#include <kwin.h>
+
+#include "client_mnu.h"
+#include "container_base.h"
+#include "global.h"
+#include "kbutton.h"
+#include "kicker.h"
+#include "kickerSettings.h"
+#include "konqbookmarkmanager.h"
+#include "menuinfo.h"
+#include "menumanager.h"
+#include "popupmenutitle.h"
+#include "quickbrowser_mnu.h"
+#include "recentapps.h"
+
+#include "k_mnu.h"
+#include "k_mnu.moc"
+
+PanelKMenu::PanelKMenu()
+ : PanelServiceMenu(QString::null, QString::null, 0, "KMenu")
+ , bookmarkMenu(0)
+ , bookmarkOwner(0)
+{
+ static const QCString dcopObjId("KMenu");
+ DCOPObject::setObjId(dcopObjId);
+ // set the first client id to some arbitrarily large value.
+ client_id = 10000;
+ // Don't automatically clear the main menu.
+ disableAutoClear();
+ actionCollection = new KActionCollection(this);
+ setCaption(i18n("K Menu"));
+ connect(Kicker::the(), SIGNAL(configurationChanged()),
+ this, SLOT(configChanged()));
+ DCOPClient *dcopClient = KApplication::dcopClient();
+ dcopClient->connectDCOPSignal(0, "appLauncher",
+ "serviceStartedByStorageId(QString,QString)",
+ dcopObjId,
+ "slotServiceStartedByStorageId(QString,QString)",
+ false);
+}
+
+PanelKMenu::~PanelKMenu()
+{
+ clearSubmenus();
+ delete bookmarkMenu;
+ delete bookmarkOwner;
+}
+
+void PanelKMenu::slotServiceStartedByStorageId(QString starter,
+ QString storageId)
+{
+ if (starter != "kmenu")
+ {
+ kdDebug() << "KMenu - updating recently used applications: " <<
+ storageId << endl;
+ KService::Ptr service = KService::serviceByStorageId(storageId);
+ updateRecentlyUsedApps(service);
+ }
+}
+
+
+bool PanelKMenu::loadSidePixmap()
+{
+ if (!KickerSettings::useSidePixmap())
+ {
+ return false;
+ }
+
+ QString sideName = KickerSettings::sidePixmapName();
+ QString sideTileName = KickerSettings::sideTileName();
+
+ QImage image;
+ image.load(locate("data", "kicker/pics/" + sideName));
+
+ if (image.isNull())
+ {
+ kdDebug(1210) << "Can't find a side pixmap" << endl;
+ return false;
+ }
+
+ KickerLib::colorize(image);
+ sidePixmap.convertFromImage(image);
+
+ image.load(locate("data", "kicker/pics/" + sideTileName));
+
+ if (image.isNull())
+ {
+ kdDebug(1210) << "Can't find a side tile pixmap" << endl;
+ return false;
+ }
+
+ KickerLib::colorize(image);
+ sideTilePixmap.convertFromImage(image);
+
+ if (sidePixmap.width() != sideTilePixmap.width())
+ {
+ kdDebug(1210) << "Pixmaps have to be the same size" << endl;
+ return false;
+ }
+
+ // pretile the pixmap to a height of at least 100 pixels
+ if (sideTilePixmap.height() < 100)
+ {
+ int tiles = (int)(100 / sideTilePixmap.height()) + 1;
+ QPixmap preTiledPixmap(sideTilePixmap.width(), sideTilePixmap.height() * tiles);
+ QPainter p(&preTiledPixmap);
+ p.drawTiledPixmap(preTiledPixmap.rect(), sideTilePixmap);
+ sideTilePixmap = preTiledPixmap;
+ }
+
+ return true;
+}
+
+void PanelKMenu::paletteChanged()
+{
+ if (!loadSidePixmap())
+ {
+ sidePixmap = sideTilePixmap = QPixmap();
+ setMinimumSize( sizeHint() );
+ }
+}
+
+void PanelKMenu::initialize()
+{
+// kdDebug(1210) << "PanelKMenu::initialize()" << endl;
+ updateRecent();
+
+ if (initialized())
+ {
+ return;
+ }
+
+ if (loadSidePixmap())
+ {
+ // in case we've been through here before, let's disconnect
+ disconnect(kapp, SIGNAL(kdisplayPaletteChanged()),
+ this, SLOT(paletteChanged()));
+ connect(kapp, SIGNAL(kdisplayPaletteChanged()),
+ this, SLOT(paletteChanged()));
+ }
+ else
+ {
+ sidePixmap = sideTilePixmap = QPixmap();
+ }
+
+ // add services
+ PanelServiceMenu::initialize();
+
+ if (KickerSettings::showMenuTitles())
+ {
+ int id;
+ id = insertItem(new PopupMenuTitle(i18n("All Applications"), font()), -1 /* id */, 0);
+ setItemEnabled( id, false );
+ id = insertItem(new PopupMenuTitle(i18n("Actions"), font()), -1 /* id */, -1);
+ setItemEnabled( id, false );
+ }
+
+ // create recent menu section
+ createRecentMenuItems();
+
+ bool need_separator = false;
+
+ // insert bookmarks
+ if (KickerSettings::useBookmarks() && kapp->authorizeKAction("bookmarks"))
+ {
+ // Need to create a new popup each time, it's deleted by subMenus.clear()
+ KPopupMenu * bookmarkParent = new KPopupMenu( this, "bookmarks" );
+ if(!bookmarkOwner)
+ bookmarkOwner = new KBookmarkOwner;
+ delete bookmarkMenu; // can't reuse old one, the popup has been deleted
+ bookmarkMenu = new KBookmarkMenu( KonqBookmarkManager::self(), bookmarkOwner, bookmarkParent, actionCollection, true, false );
+
+ insertItem(KickerLib::menuIconSet("bookmark"), i18n("Bookmarks"), bookmarkParent);
+
+ subMenus.append(bookmarkParent);
+ need_separator = true;
+ }
+
+ // insert quickbrowser
+ if (KickerSettings::useBrowser())
+ {
+ PanelQuickBrowser *browserMnu = new PanelQuickBrowser(this);
+ browserMnu->initialize();
+
+ insertItem(KickerLib::menuIconSet("kdisknav"),
+ i18n("Quick Browser"),
+ KickerLib::reduceMenu(browserMnu));
+ subMenus.append(browserMnu);
+ need_separator = true;
+ }
+
+ // insert dynamic menus
+ QStringList menu_ext = KickerSettings::menuExtensions();
+ if (!menu_ext.isEmpty())
+ {
+ for (QStringList::ConstIterator it=menu_ext.begin(); it!=menu_ext.end(); ++it)
+ {
+ MenuInfo info(*it);
+ if (!info.isValid())
+ continue;
+
+ KPanelMenu *menu = info.load();
+ if (menu)
+ {
+ insertItem(KickerLib::menuIconSet(info.icon()), info.name(), menu);
+ dynamicSubMenus.append(menu);
+ need_separator = true;
+ }
+ }
+ }
+
+ if (need_separator)
+ insertSeparator();
+
+ // insert client menus, if any
+ if (clients.count() > 0) {
+ QIntDictIterator<KickerClientMenu> it(clients);
+ while (it){
+ if (it.current()->text.at(0) != '.')
+ insertItem(
+ it.current()->icon,
+ it.current()->text,
+ it.current(),
+ it.currentKey()
+ );
+ ++it;
+ }
+ insertSeparator();
+ }
+
+ // run command
+ if (kapp->authorize("run_command"))
+ {
+ insertItem(KickerLib::menuIconSet("run"),
+ i18n("Run Command..."),
+ this,
+ SLOT( slotRunCommand()));
+ insertSeparator();
+ }
+
+ if (DM().isSwitchable() && kapp->authorize("switch_user"))
+ {
+ sessionsMenu = new QPopupMenu( this );
+ insertItem(KickerLib::menuIconSet("switchuser"), i18n("Switch User"), sessionsMenu);
+ connect( sessionsMenu, SIGNAL(aboutToShow()), SLOT(slotPopulateSessions()) );
+ connect( sessionsMenu, SIGNAL(activated(int)), SLOT(slotSessionActivated(int)) );
+ }
+
+ /*
+ If the user configured ksmserver to
+ */
+ KConfig ksmserver("ksmserverrc", false, false);
+ ksmserver.setGroup("General");
+ if (ksmserver.readEntry( "loginMode" ) == "restoreSavedSession")
+ {
+ insertItem(KickerLib::menuIconSet("filesave"), i18n("Save Session"), this, SLOT(slotSaveSession()));
+ }
+
+ if (kapp->authorize("lock_screen"))
+ {
+ insertItem(KickerLib::menuIconSet("lock"), i18n("Lock Session"), this, SLOT(slotLock()));
+ }
+
+ if (kapp->authorize("logout"))
+ {
+ insertItem(KickerLib::menuIconSet("exit"), i18n("Log Out..."), this, SLOT(slotLogout()));
+ }
+
+#if 0
+ // WABA: tear off handles don't work together with dynamically updated
+ // menus. We can't update the menu while torn off, and we don't know
+ // when it is torn off.
+ if (KGlobalSettings::insertTearOffHandle())
+ insertTearOffHandle();
+#endif
+
+ setInitialized(true);
+}
+
+int PanelKMenu::insertClientMenu(KickerClientMenu *p)
+{
+ int id = client_id;
+ clients.insert(id, p);
+ slotClear();
+ return id;
+}
+
+void PanelKMenu::removeClientMenu(int id)
+{
+ clients.remove(id);
+ removeItem(id);
+ slotClear();
+}
+
+extern int kicker_screen_number;
+
+void PanelKMenu::slotLock()
+{
+ QCString appname( "kdesktop" );
+ if ( kicker_screen_number )
+ appname.sprintf("kdesktop-screen-%d", kicker_screen_number);
+ kapp->dcopClient()->send(appname, "KScreensaverIface", "lock()", "");
+}
+
+void PanelKMenu::slotLogout()
+{
+ kapp->requestShutDown();
+}
+
+void PanelKMenu::slotPopulateSessions()
+{
+ int p = 0;
+ DM dm;
+
+ sessionsMenu->clear();
+ if (kapp->authorize("start_new_session") && (p = dm.numReserve()) >= 0)
+ {
+ if (kapp->authorize("lock_screen"))
+ sessionsMenu->insertItem(/*SmallIconSet("lockfork"),*/ i18n("Lock Current && Start New Session"), 100 );
+ sessionsMenu->insertItem(SmallIconSet("fork"), i18n("Start New Session"), 101 );
+ if (!p) {
+ sessionsMenu->setItemEnabled( 100, false );
+ sessionsMenu->setItemEnabled( 101, false );
+ }
+ sessionsMenu->insertSeparator();
+ }
+ SessList sess;
+ if (dm.localSessions( sess ))
+ for (SessList::ConstIterator it = sess.begin(); it != sess.end(); ++it) {
+ int id = sessionsMenu->insertItem( DM::sess2Str( *it ), (*it).vt );
+ if (!(*it).vt)
+ sessionsMenu->setItemEnabled( id, false );
+ if ((*it).self)
+ sessionsMenu->setItemChecked( id, true );
+ }
+}
+
+void PanelKMenu::slotSessionActivated( int ent )
+{
+ if (ent == 100)
+ doNewSession( true );
+ else if (ent == 101)
+ doNewSession( false );
+ else if (!sessionsMenu->isItemChecked( ent ))
+ DM().lockSwitchVT( ent );
+}
+
+void PanelKMenu::doNewSession( bool lock )
+{
+ int result = KMessageBox::warningContinueCancel(
+ kapp->desktop()->screen(kapp->desktop()->screenNumber(this)),
+ i18n("<p>You have chosen to open another desktop session.<br>"
+ "The current session will be hidden "
+ "and a new login screen will be displayed.<br>"
+ "An F-key is assigned to each session; "
+ "F%1 is usually assigned to the first session, "
+ "F%2 to the second session and so on. "
+ "You can switch between sessions by pressing "
+ "Ctrl, Alt and the appropriate F-key at the same time. "
+ "Additionally, the KDE Panel and Desktop menus have "
+ "actions for switching between sessions.</p>")
+ .arg(7).arg(8),
+ i18n("Warning - New Session"),
+ KGuiItem(i18n("&Start New Session"), "fork"),
+ ":confirmNewSession",
+ KMessageBox::PlainCaption | KMessageBox::Notify);
+
+ if (result==KMessageBox::Cancel)
+ return;
+
+ if (lock)
+ slotLock();
+
+ DM().startReserve();
+}
+
+void PanelKMenu::slotSaveSession()
+{
+ QByteArray data;
+ kapp->dcopClient()->send( "ksmserver", "default",
+ "saveCurrentSession()", data );
+}
+
+void PanelKMenu::slotRunCommand()
+{
+ QByteArray data;
+ QCString appname( "kdesktop" );
+ if ( kicker_screen_number )
+ appname.sprintf("kdesktop-screen-%d", kicker_screen_number);
+
+ kapp->updateRemoteUserTimestamp( appname );
+ kapp->dcopClient()->send( appname, "KDesktopIface",
+ "popupExecuteCommand()", data );
+}
+
+void PanelKMenu::slotEditUserContact()
+{
+}
+
+void PanelKMenu::setMinimumSize(const QSize & s)
+{
+ KPanelMenu::setMinimumSize(s.width() + sidePixmap.width(), s.height());
+}
+
+void PanelKMenu::setMaximumSize(const QSize & s)
+{
+ KPanelMenu::setMaximumSize(s.width() + sidePixmap.width(), s.height());
+}
+
+void PanelKMenu::setMinimumSize(int w, int h)
+{
+ KPanelMenu::setMinimumSize(w + sidePixmap.width(), h);
+}
+
+void PanelKMenu::setMaximumSize(int w, int h)
+{
+ KPanelMenu::setMaximumSize(w + sidePixmap.width(), h);
+}
+
+void PanelKMenu::showMenu()
+{
+ kdDebug( 1210 ) << "PanelKMenu::showMenu()" << endl;
+ PanelPopupButton *kButton = MenuManager::the()->findKButtonFor(this);
+ if (kButton)
+ {
+ adjustSize();
+ kButton->showMenu();
+ }
+ else
+ {
+ show();
+ }
+}
+
+QRect PanelKMenu::sideImageRect()
+{
+ return QStyle::visualRect( QRect( frameWidth(), frameWidth(), sidePixmap.width(),
+ height() - 2*frameWidth() ), this );
+}
+
+void PanelKMenu::resizeEvent(QResizeEvent * e)
+{
+// kdDebug(1210) << "PanelKMenu::resizeEvent():" << endl;
+// kdDebug(1210) << geometry().width() << ", " << geometry().height() << endl;
+
+ PanelServiceMenu::resizeEvent(e);
+
+ setFrameRect( QStyle::visualRect( QRect( sidePixmap.width(), 0,
+ width() - sidePixmap.width(), height() ), this ) );
+}
+
+//Workaround Qt3.3.x sizing bug, by ensuring we're always wide enough.
+void PanelKMenu::resize(int width, int height)
+{
+ width = kMax(width, maximumSize().width());
+ PanelServiceMenu::resize(width, height);
+}
+
+QSize PanelKMenu::sizeHint() const
+{
+ QSize s = PanelServiceMenu::sizeHint();
+// kdDebug(1210) << "PanelKMenu::sizeHint()" << endl;
+// kdDebug(1210) << s.width() << ", " << s.height() << endl;
+ return s;
+}
+
+void PanelKMenu::paintEvent(QPaintEvent * e)
+{
+ if (sidePixmap.isNull()) {
+ PanelServiceMenu::paintEvent(e);
+ return;
+ }
+
+ QPainter p(this);
+ p.setClipRegion(e->region());
+
+ style().drawPrimitive( QStyle::PE_PanelPopup, &p,
+ QRect( 0, 0, width(), height() ),
+ colorGroup(), QStyle::Style_Default,
+ QStyleOption( frameWidth(), 0 ) );
+
+ QRect r = sideImageRect();
+ r.setBottom( r.bottom() - sidePixmap.height() );
+ if ( r.intersects( e->rect() ) )
+ {
+ p.drawTiledPixmap( r, sideTilePixmap );
+ }
+
+ r = sideImageRect();
+ r.setTop( r.bottom() - sidePixmap.height() );
+ if ( r.intersects( e->rect() ) )
+ {
+ QRect drawRect = r.intersect( e->rect() );
+ QRect pixRect = drawRect;
+ pixRect.moveBy( -r.left(), -r.top() );
+ p.drawPixmap( drawRect.topLeft(), sidePixmap, pixRect );
+ }
+
+ drawContents( &p );
+}
+
+QMouseEvent PanelKMenu::translateMouseEvent( QMouseEvent* e )
+{
+ QRect side = sideImageRect();
+
+ if ( !side.contains( e->pos() ) )
+ return *e;
+
+ QPoint newpos( e->pos() );
+ QApplication::reverseLayout() ?
+ newpos.setX( newpos.x() - side.width() ) :
+ newpos.setX( newpos.x() + side.width() );
+ QPoint newglobal( e->globalPos() );
+ QApplication::reverseLayout() ?
+ newglobal.setX( newpos.x() - side.width() ) :
+ newglobal.setX( newpos.x() + side.width() );
+
+ return QMouseEvent( e->type(), newpos, newglobal, e->button(), e->state() );
+}
+
+void PanelKMenu::mousePressEvent(QMouseEvent * e)
+{
+ QMouseEvent newEvent = translateMouseEvent(e);
+ PanelServiceMenu::mousePressEvent( &newEvent );
+}
+
+void PanelKMenu::mouseReleaseEvent(QMouseEvent *e)
+{
+ QMouseEvent newEvent = translateMouseEvent(e);
+ PanelServiceMenu::mouseReleaseEvent( &newEvent );
+}
+
+void PanelKMenu::mouseMoveEvent(QMouseEvent *e)
+{
+ QMouseEvent newEvent = translateMouseEvent(e);
+ PanelServiceMenu::mouseMoveEvent( &newEvent );
+}
+
+void PanelKMenu::configChanged()
+{
+ RecentlyLaunchedApps::the().m_bNeedToUpdate = false;
+ RecentlyLaunchedApps::the().configChanged();
+ PanelServiceMenu::configChanged();
+}
+
+// create and fill "recent" section at first
+void PanelKMenu::createRecentMenuItems()
+{
+ RecentlyLaunchedApps::the().m_nNumMenuItems = 0;
+
+ QStringList RecentApps;
+ RecentlyLaunchedApps::the().getRecentApps(RecentApps);
+
+ if (RecentApps.count() > 0)
+ {
+ bool bSeparator = KickerSettings::showMenuTitles();
+ int nId = serviceMenuEndId() + 1;
+ int nIndex = KickerSettings::showMenuTitles() ? 1 : 0;
+
+ for (QValueList<QString>::ConstIterator it =
+ RecentApps.fromLast(); /*nop*/; --it)
+ {
+ KService::Ptr s = KService::serviceByDesktopPath(*it);
+ if (!s)
+ {
+ RecentlyLaunchedApps::the().removeItem(*it);
+ }
+ else
+ {
+ if (bSeparator)
+ {
+ bSeparator = false;
+ int id = insertItem(
+ new PopupMenuTitle(
+ RecentlyLaunchedApps::the().caption(), font()),
+ serviceMenuEndId(), 0);
+ setItemEnabled( id, false );
+ }
+ insertMenuItem(s, nId++, nIndex);
+ RecentlyLaunchedApps::the().m_nNumMenuItems++;
+ }
+
+ if (it == RecentApps.begin())
+ {
+ break;
+ }
+ }
+
+ if (!KickerSettings::showMenuTitles())
+ {
+ insertSeparator(RecentlyLaunchedApps::the().m_nNumMenuItems);
+ }
+ }
+}
+
+void PanelKMenu::clearSubmenus()
+{
+ // we don't need to delete these on the way out since the libloader
+ // handles them for us
+ if (QApplication::closingDown())
+ {
+ return;
+ }
+
+ for (PopupMenuList::const_iterator it = dynamicSubMenus.constBegin();
+ it != dynamicSubMenus.constEnd();
+ ++it)
+ {
+ delete *it;
+ }
+ dynamicSubMenus.clear();
+
+ PanelServiceMenu::clearSubmenus();
+}
+
+void PanelKMenu::updateRecent()
+{
+ if (!RecentlyLaunchedApps::the().m_bNeedToUpdate)
+ {
+ return;
+ }
+
+ RecentlyLaunchedApps::the().m_bNeedToUpdate = false;
+
+ int nId = serviceMenuEndId() + 1;
+
+ // remove previous items
+ if (RecentlyLaunchedApps::the().m_nNumMenuItems > 0)
+ {
+ // -1 --> menu title
+ int i = KickerSettings::showMenuTitles() ? -1 : 0;
+ for (; i < RecentlyLaunchedApps::the().m_nNumMenuItems; i++)
+ {
+ removeItem(nId + i);
+ entryMap_.remove(nId + i);
+ }
+ RecentlyLaunchedApps::the().m_nNumMenuItems = 0;
+
+ if (!KickerSettings::showMenuTitles())
+ {
+ removeItemAt(0);
+ }
+ }
+
+ // insert new items
+ QStringList RecentApps;
+ RecentlyLaunchedApps::the().getRecentApps(RecentApps);
+
+ if (RecentApps.count() > 0)
+ {
+ bool bNeedSeparator = KickerSettings::showMenuTitles();
+ for (QValueList<QString>::ConstIterator it = RecentApps.fromLast();
+ /*nop*/; --it)
+ {
+ KService::Ptr s = KService::serviceByDesktopPath(*it);
+ if (!s)
+ {
+ RecentlyLaunchedApps::the().removeItem(*it);
+ }
+ else
+ {
+ if (bNeedSeparator)
+ {
+ bNeedSeparator = false;
+ int id = insertItem(new PopupMenuTitle(
+ RecentlyLaunchedApps::the().caption(),
+ font()), nId - 1, 0);
+ setItemEnabled( id, false );
+ }
+ insertMenuItem(s, nId++, KickerSettings::showMenuTitles() ?
+ 1 : 0);
+ RecentlyLaunchedApps::the().m_nNumMenuItems++;
+ }
+
+ if (it == RecentApps.begin())
+ break;
+ }
+
+ if (!KickerSettings::showMenuTitles())
+ {
+ insertSeparator(RecentlyLaunchedApps::the().m_nNumMenuItems);
+ }
+ }
+}
+
+void PanelKMenu::clearRecentMenuItems()
+{
+ RecentlyLaunchedApps::the().clearRecentApps();
+ RecentlyLaunchedApps::the().save();
+ RecentlyLaunchedApps::the().m_bNeedToUpdate = true;
+ updateRecent();
+}
+
+
diff --git a/kicker/kicker/ui/k_mnu.h b/kicker/kicker/ui/k_mnu.h
new file mode 100644
index 000000000..f20cde06d
--- /dev/null
+++ b/kicker/kicker/ui/k_mnu.h
@@ -0,0 +1,106 @@
+/*****************************************************************
+
+Copyright (c) 1996-2000 the kicker authors. See file AUTHORS.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#ifndef __k_mnu_h__
+#define __k_mnu_h__
+
+#include <dcopobject.h>
+#include <qintdict.h>
+#include <qpixmap.h>
+
+#include "service_mnu.h"
+
+class KickerClientMenu;
+class KBookmarkMenu;
+class KActionCollection;
+class KBookmarkOwner;
+class Panel;
+
+class PanelKMenu : public PanelServiceMenu, public DCOPObject
+{
+ Q_OBJECT
+ K_DCOP
+
+k_dcop:
+ void slotServiceStartedByStorageId(QString starter, QString desktopPath);
+
+public:
+ PanelKMenu();
+ ~PanelKMenu();
+
+ int insertClientMenu(KickerClientMenu *p);
+ void removeClientMenu(int id);
+
+ virtual QSize sizeHint() const;
+ virtual void setMinimumSize(const QSize &);
+ virtual void setMaximumSize(const QSize &);
+ virtual void setMinimumSize(int, int);
+ virtual void setMaximumSize(int, int);
+ virtual void showMenu();
+ void clearRecentMenuItems();
+
+public slots:
+ virtual void initialize();
+
+ //### KDE4: workaround for Qt bug, remove later
+ virtual void resize(int width, int height);
+
+protected slots:
+ void slotLock();
+ void slotLogout();
+ void slotPopulateSessions();
+ void slotSessionActivated( int );
+ void slotSaveSession();
+ void slotRunCommand();
+ void slotEditUserContact();
+ void paletteChanged();
+ virtual void configChanged();
+ void updateRecent();
+
+protected:
+ QRect sideImageRect();
+ QMouseEvent translateMouseEvent(QMouseEvent* e);
+ void resizeEvent(QResizeEvent *);
+ void paintEvent(QPaintEvent *);
+ void mousePressEvent(QMouseEvent *);
+ void mouseReleaseEvent(QMouseEvent *);
+ void mouseMoveEvent(QMouseEvent *);
+ bool loadSidePixmap();
+ void doNewSession(bool lock);
+ void createRecentMenuItems();
+ virtual void clearSubmenus();
+
+private:
+ QPopupMenu *sessionsMenu;
+ QPixmap sidePixmap;
+ QPixmap sideTilePixmap;
+ int client_id;
+ bool delay_init;
+ QIntDict<KickerClientMenu> clients;
+ KBookmarkMenu *bookmarkMenu;
+ KActionCollection *actionCollection;
+ KBookmarkOwner *bookmarkOwner;
+ PopupMenuList dynamicSubMenus;
+};
+
+#endif
diff --git a/kicker/kicker/ui/nonKDEButtonSettings.ui b/kicker/kicker/ui/nonKDEButtonSettings.ui
new file mode 100644
index 000000000..5c44aca85
--- /dev/null
+++ b/kicker/kicker/ui/nonKDEButtonSettings.ui
@@ -0,0 +1,221 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>NonKDEButtonSettings</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>NonKDEButtonSettings</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>436</width>
+ <height>225</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string></string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <widget class="KURLRequester" row="7" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>m_exec</cstring>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Enter the name of the executable file to be run when this button is selected. If it is not in your $PATH then you will need to provide an absolute path.</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="8" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>textLabel3</cstring>
+ </property>
+ <property name="text">
+ <string>Co&amp;mmand line arguments (optional):</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>m_commandLine</cstring>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Enter any command line options that should be passed to the command here.
+
+&lt;i&gt;Example&lt;/i&gt;: For the command `rm -rf` enter "-rf" in this text box.</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="10" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>m_inTerm</cstring>
+ </property>
+ <property name="text">
+ <string>Run in a &amp;terminal window</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Select this option if the command is a command line application and you wish to be able to see its output when run.</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="9" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>m_commandLine</cstring>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Enter any command line options that should be passed to the command here.
+
+&lt;i&gt;Example&lt;/i&gt;: For the command `rm -rf` enter "-rf" in this text box.</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="6" column="0">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Executable:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>m_exec</cstring>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Enter the name of the executable file to be run when this button is selected. If it is not in your $PATH then you will need to provide an absolute path.</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="1" column="1">
+ <property name="name">
+ <cstring>m_title</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>15</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Enter the name you would like to appear for this button here.</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="1">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Button title:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>m_title</cstring>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Enter the name you would like to appear for this button here.</string>
+ </property>
+ </widget>
+ <spacer row="11" column="1">
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>16</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="KIconButton" row="0" column="0" rowspan="3" colspan="1">
+ <property name="name">
+ <cstring>m_icon</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>58</width>
+ <height>58</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>58</width>
+ <height>58</height>
+ </size>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="iconSize">
+ <number>48</number>
+ </property>
+ </widget>
+ <widget class="QLabel" row="4" column="0">
+ <property name="name">
+ <cstring>textLabel4</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Description:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>m_description</cstring>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Enter the name you would like to appear for this button here.</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="5" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>m_description</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>15</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Enter the name you would like to appear for this button here.</string>
+ </property>
+ </widget>
+ <spacer row="2" column="1">
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Minimum</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>8</height>
+ </size>
+ </property>
+ </spacer>
+ </grid>
+</widget>
+<tabstops>
+ <tabstop>m_icon</tabstop>
+ <tabstop>m_title</tabstop>
+ <tabstop>m_description</tabstop>
+ <tabstop>m_exec</tabstop>
+ <tabstop>m_commandLine</tabstop>
+ <tabstop>m_inTerm</tabstop>
+</tabstops>
+<layoutdefaults spacing="6" margin="11"/>
+<layoutfunctions spacing="KDialog::spacingHint" margin="KDialog::marginHint"/>
+</UI>
diff --git a/kicker/kicker/ui/panelmenuiteminfo.h b/kicker/kicker/ui/panelmenuiteminfo.h
new file mode 100644
index 000000000..29faca50f
--- /dev/null
+++ b/kicker/kicker/ui/panelmenuiteminfo.h
@@ -0,0 +1,103 @@
+/*****************************************************************
+
+Copyright (c) 2003 Aaron J. Seigo
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#ifndef PANELMENUITEMINFO_H
+#define PANELMENUITEMINFO_H
+
+#include <qpopupmenu.h>
+#include <qstring.h>
+
+#include <kiconloader.h>
+
+// a little class meant to be used to store menu items for sorting then later
+// plugging into a popup menu
+
+class PanelMenuItemInfo
+{
+ public:
+ PanelMenuItemInfo()
+ : m_recvr(0), m_id(-1) {}
+
+ PanelMenuItemInfo(const QString& iconName, const QString& visibleName, const QObject* recvr, const QCString& slot, int id = -1)
+ : m_icon(iconName), m_name(visibleName), m_slot_(slot), m_recvr(recvr), m_id(id) {}
+
+ PanelMenuItemInfo(const QString& iconName, const QString& visibleName, int id = -1)
+ : m_icon(iconName), m_name(visibleName), m_recvr(0), m_id(id) {}
+
+ PanelMenuItemInfo(const PanelMenuItemInfo& c)
+ : m_icon(c.m_icon), m_name(c.m_name), m_slot_(c.m_slot_), m_recvr(c.m_recvr), m_id(c.m_id) {}
+
+ PanelMenuItemInfo& operator=(const PanelMenuItemInfo& c)
+ {
+ m_icon = c.m_icon;
+ m_name = c.m_name;
+ m_slot_ = c.m_slot_;
+ m_recvr = c.m_recvr;
+ m_id = c.m_id;
+ return *this;
+ }
+
+ bool operator<(const PanelMenuItemInfo& rh)
+ {
+ return m_name.lower() < rh.m_name.lower();
+ }
+
+ bool operator<=(const PanelMenuItemInfo& rh)
+ {
+ return m_name.lower() <= rh.m_name.lower();
+ }
+
+ bool operator>(const PanelMenuItemInfo& rh)
+ {
+ return m_name.lower() > rh.m_name.lower();
+ }
+
+ int plug(QPopupMenu* menu)
+ {
+ if (!m_icon.isEmpty() && m_icon != "unknown")
+ {
+ if (m_recvr && !m_slot_.isEmpty())
+ {
+ return menu->insertItem(SmallIconSet(m_icon), m_name, m_recvr, m_slot_, 0, m_id);
+ }
+
+ return menu->insertItem(SmallIconSet(m_icon), m_name, m_id);
+ }
+ else if (m_recvr && !m_slot_.isEmpty())
+ {
+ return menu->insertItem(m_name, m_recvr, m_slot_, 0, m_id);
+ }
+
+ return menu->insertItem(m_name, m_id);
+ }
+
+ private:
+ QString m_icon;
+ QString m_name;
+ QCString m_slot_; // HPUX namespace is polluted with m_slot
+ const QObject* m_recvr;
+ int m_id;
+};
+
+#endif
+
diff --git a/kicker/kicker/ui/popupmenutitle.cpp b/kicker/kicker/ui/popupmenutitle.cpp
new file mode 100644
index 000000000..adf44b802
--- /dev/null
+++ b/kicker/kicker/ui/popupmenutitle.cpp
@@ -0,0 +1,33 @@
+/*****************************************************************
+
+Copyright (c) 2000 Matthias Elter <elter@kde.org>
+ Matthias Ettrich <ettrich@kde.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#include "popupmenutitle.h"
+
+PopupMenuTitle::PopupMenuTitle(const QString &name, const QFont &font) :
+ QCustomMenuItem(),
+ m_desktopName(name),
+ m_font(font)
+{
+ m_font.setBold(true);
+}
diff --git a/kicker/kicker/ui/popupmenutitle.h b/kicker/kicker/ui/popupmenutitle.h
new file mode 100644
index 000000000..4724c88c7
--- /dev/null
+++ b/kicker/kicker/ui/popupmenutitle.h
@@ -0,0 +1,85 @@
+/*****************************************************************
+
+Copyright (c) 2000 Matthias Elter <elter@kde.org>
+ Matthias Ettrich <ettrich@kde.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#ifndef POPUPMENUTITLE_H
+#define POPUPMENUTITLE_H
+
+#include <qfont.h>
+#include <qstring.h>
+#include <qstyle.h>
+#include <qpainter.h>
+#include <qmenudata.h>
+
+#include <kapplication.h>
+
+class PopupMenuTitle : public QCustomMenuItem
+{
+public:
+ PopupMenuTitle(const QString &name, const QFont &font);
+
+ bool fullSpan () const { return true; }
+
+ void paint(QPainter* p, const QColorGroup& cg,
+ bool /* act */, bool /*enabled*/,
+ int x, int y, int w, int h)
+ {
+ p->save();
+ QRect r(x, y, w, h);
+ kapp->style().drawPrimitive(QStyle::PE_HeaderSection,
+ p, r, cg);
+
+ if (!m_desktopName.isEmpty())
+ {
+ p->setPen(cg.buttonText());
+ p->setFont(m_font);
+ p->drawText(x, y, w, h,
+ AlignCenter | SingleLine,
+ m_desktopName);
+ }
+
+ p->setPen(cg.highlight());
+ p->drawLine(0, 0, r.right(), 0);
+ p->restore();
+ }
+
+ void setFont(const QFont &font)
+ {
+ m_font = font;
+ m_font.setBold(true);
+ }
+
+ QSize sizeHint()
+ {
+ QSize size = QFontMetrics(m_font).size(AlignHCenter, m_desktopName);
+ size.setHeight(size.height() +
+ (kapp->style().pixelMetric(QStyle::PM_DefaultFrameWidth) * 2 + 1));
+ return size;
+ }
+
+ private:
+ QString m_desktopName;
+ QFont m_font;
+};
+
+#endif
diff --git a/kicker/kicker/ui/quickbrowser_mnu.cpp b/kicker/kicker/ui/quickbrowser_mnu.cpp
new file mode 100644
index 000000000..583fc1deb
--- /dev/null
+++ b/kicker/kicker/ui/quickbrowser_mnu.cpp
@@ -0,0 +1,60 @@
+/*****************************************************************
+
+Copyright (c) 2001 Matthias Elter <elter@kde.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#include <qdir.h>
+
+#include <kapplication.h>
+#include <klocale.h>
+#include <kglobal.h>
+#include <kiconloader.h>
+#include <kurl.h>
+
+#include "browser_mnu.h"
+#include "quickbrowser_mnu.h"
+#include "quickbrowser_mnu.moc"
+
+PanelQuickBrowser::PanelQuickBrowser(QWidget *parent, const char *name)
+ : KPanelMenu("", parent, name) {}
+
+void PanelQuickBrowser::initialize()
+{
+ if(initialized()) return;
+ setInitialized(true);
+
+ KURL url;
+
+ url.setPath(QDir::homeDirPath());
+ if (kapp->authorizeURLAction("list", KURL(), url))
+ insertItem(SmallIcon("kfm_home"), i18n("&Home Folder"),
+ new PanelBrowserMenu(url.path(), this));
+
+ url.setPath(QDir::rootDirPath());
+ if (kapp->authorizeURLAction("list", KURL(), url))
+ insertItem(SmallIcon("folder_red"), i18n("&Root Folder"),
+ new PanelBrowserMenu(url.path(), this));
+
+ url.setPath(QDir::rootDirPath() + "etc");
+ if (kapp->authorizeURLAction("list", KURL(), url))
+ insertItem(SmallIcon("folder_yellow"), i18n("System &Configuration"),
+ new PanelBrowserMenu(url.path(), this));
+}
diff --git a/kicker/kicker/ui/quickbrowser_mnu.h b/kicker/kicker/ui/quickbrowser_mnu.h
new file mode 100644
index 000000000..9d9582a8b
--- /dev/null
+++ b/kicker/kicker/ui/quickbrowser_mnu.h
@@ -0,0 +1,43 @@
+/*****************************************************************
+
+Copyright (c) 2001 Matthias Elter <elter@kde.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#ifndef __quickbrowser_mnu_h__
+#define __quickbrowser_mnu_h__
+
+#include <kpanelmenu.h>
+
+class PanelQuickBrowser : public KPanelMenu
+{
+ Q_OBJECT
+
+public:
+ PanelQuickBrowser(QWidget *parent=0, const char *name=0);
+
+public slots:
+ virtual void initialize();
+
+protected slots:
+ void slotExec(int) {}
+};
+
+#endif
diff --git a/kicker/kicker/ui/recentapps.cpp b/kicker/kicker/ui/recentapps.cpp
new file mode 100644
index 000000000..54241cb29
--- /dev/null
+++ b/kicker/kicker/ui/recentapps.cpp
@@ -0,0 +1,172 @@
+/*****************************************************************
+
+Copyright (c) 2000 the kicker authors. See file AUTHORS.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#include <time.h>
+
+#include <qregexp.h>
+#include <qstringlist.h>
+
+#include <dcopclient.h>
+#include <kapplication.h>
+#include <kdebug.h>
+#include <kglobal.h>
+#include <klocale.h>
+
+#include "kickerSettings.h"
+
+#include "recentapps.h"
+
+RecentlyLaunchedApps& RecentlyLaunchedApps::the()
+{
+ static RecentlyLaunchedApps obj;
+ return obj;
+}
+
+RecentlyLaunchedApps::RecentlyLaunchedApps()
+{
+ // set defaults
+ m_nNumMenuItems = 0;
+ m_bNeedToUpdate = false;
+ m_bInitialised = false;
+ init();
+}
+
+void RecentlyLaunchedApps::init()
+{
+ if (m_bInitialised)
+ {
+ return;
+ }
+
+ m_nNumMenuItems = 0;
+ m_appInfos.clear();
+
+ configChanged();
+
+ QStringList recentApps = KickerSettings::recentAppsStat();
+
+ for (QStringList::ConstIterator it = recentApps.begin();
+ it != recentApps.end(); ++it )
+ {
+ QRegExp re( "(\\d*) (\\d*) (.*)" );
+ if (re.search(*it) != -1)
+ {
+ int nCount = re.cap(1).toInt();
+ long lTime = re.cap(2).toLong();
+ QString szPath = re.cap(3);
+ m_appInfos.append(RecentlyLaunchedAppInfo(
+ szPath, nCount, time_t(lTime)));
+ }
+ }
+
+ qHeapSort(m_appInfos);
+
+ m_bInitialised = true;
+}
+
+void RecentlyLaunchedApps::configChanged()
+{
+ qHeapSort(m_appInfos);
+}
+
+void RecentlyLaunchedApps::save()
+{
+ QStringList recentApps;
+
+ for (QValueList<RecentlyLaunchedAppInfo>::const_iterator it =
+ m_appInfos.constBegin(); it != m_appInfos.constEnd(); ++it)
+ {
+ recentApps.append(QString("%1 %2 %3").arg((*it).getLaunchCount())
+ .arg((*it).getLastLaunchTime())
+ .arg((*it).getDesktopPath()));
+ }
+
+ KickerSettings::setRecentAppsStat(recentApps);
+ KickerSettings::writeConfig();
+}
+
+void RecentlyLaunchedApps::appLaunched(const QString& strApp)
+{
+ // Inform other applications (like the quickstarter applet)
+ // that an application was started
+ QByteArray params;
+ QDataStream stream(params, IO_WriteOnly);
+ stream << launchDCOPSignalSource() << strApp;
+ KApplication::kApplication()->dcopClient()->emitDCOPSignal("appLauncher",
+ "serviceStartedByStorageId(QString,QString)", params);
+
+ for (QValueList<RecentlyLaunchedAppInfo>::iterator it = m_appInfos.begin();
+ it != m_appInfos.end(); ++it)
+ {
+ if ((*it).getDesktopPath() == strApp)
+ {
+ (*it).increaseLaunchCount();
+ (*it).setLastLaunchTime(time(0));
+ qHeapSort(m_appInfos);
+ return;
+ }
+ }
+
+ m_appInfos.append(RecentlyLaunchedAppInfo(strApp, 1, time(0)));
+ qHeapSort(m_appInfos);
+}
+
+void RecentlyLaunchedApps::getRecentApps(QStringList& recentApps)
+{
+ recentApps.clear();
+
+ int maximumNum = KickerSettings::numVisibleEntries();
+ int i = 0;
+ for (QValueList<RecentlyLaunchedAppInfo>::const_iterator it =
+ m_appInfos.constBegin();
+ it != m_appInfos.constEnd() && i < maximumNum;
+ ++it, ++i)
+ {
+ recentApps.append((*it).getDesktopPath());
+ }
+}
+
+void RecentlyLaunchedApps::removeItem( const QString& strName )
+{
+ for (QValueList<RecentlyLaunchedAppInfo>::iterator it = m_appInfos.begin();
+ it != m_appInfos.end(); ++it)
+ {
+ if ((*it).getDesktopPath() == strName)
+ {
+ m_appInfos.erase(it);
+ return;
+ }
+ }
+}
+
+void RecentlyLaunchedApps::clearRecentApps()
+{
+ m_appInfos.clear();
+}
+
+QString RecentlyLaunchedApps::caption() const
+{
+ return KickerSettings::recentVsOften() ?
+ i18n("Recently Used Applications") :
+ i18n("Most Used Applications");
+}
diff --git a/kicker/kicker/ui/recentapps.h b/kicker/kicker/ui/recentapps.h
new file mode 100644
index 000000000..0582cc166
--- /dev/null
+++ b/kicker/kicker/ui/recentapps.h
@@ -0,0 +1,99 @@
+/*****************************************************************
+
+Copyright (c) 2000 the kicker authors. See file AUTHORS.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#ifndef __recentapps_h__
+#define __recentapps_h__
+
+#include <qvaluelist.h>
+
+class RecentlyLaunchedApps;
+
+class RecentlyLaunchedAppInfo
+{
+public:
+ RecentlyLaunchedAppInfo()
+ {
+ m_launchCount = 0;
+ m_lastLaunchTime = 0;
+ }
+
+ RecentlyLaunchedAppInfo(const QString& desktopPath, int nLaunchCount, time_t lastLaunchTime)
+ {
+ m_desktopPath = desktopPath;
+ m_launchCount = nLaunchCount;
+ m_lastLaunchTime = lastLaunchTime;
+ }
+
+ RecentlyLaunchedAppInfo(const RecentlyLaunchedAppInfo& clone)
+ {
+ m_desktopPath = clone.m_desktopPath;
+ m_launchCount = clone.m_launchCount;
+ m_lastLaunchTime = clone.m_lastLaunchTime;
+ }
+
+ bool operator<(const RecentlyLaunchedAppInfo& rhs)
+ {
+ // Sort items in descending order according to either last launch time or launch count.
+ return KickerSettings::recentVsOften() ?
+ m_lastLaunchTime > rhs.m_lastLaunchTime:
+ m_launchCount > rhs.m_launchCount;
+ }
+
+ QString getDesktopPath() const { return m_desktopPath; }
+ int getLaunchCount() const { return m_launchCount; };
+ time_t getLastLaunchTime() const { return m_lastLaunchTime; };
+ void increaseLaunchCount() { m_launchCount++; };
+ void setLaunchCount(int nLaunchCount) { m_launchCount = nLaunchCount; };
+ void setLastLaunchTime(time_t lastLaunch) { m_lastLaunchTime = lastLaunch; };
+
+private:
+ QString m_desktopPath;
+ int m_launchCount;
+ time_t m_lastLaunchTime;
+};
+
+class RecentlyLaunchedApps
+{
+public:
+ static RecentlyLaunchedApps& the();
+ void init();
+ void configChanged();
+ void save();
+ void clearRecentApps();
+ void appLaunched(const QString & strApp);
+ void getRecentApps(QStringList & RecentApps);
+ void removeItem(const QString &strName);
+ QString caption() const;
+
+ int m_nNumMenuItems;
+ bool m_bNeedToUpdate;
+
+private:
+ QString launchDCOPSignalSource() { return "kmenu"; }
+ RecentlyLaunchedApps();
+
+ QValueList<RecentlyLaunchedAppInfo> m_appInfos;
+ bool m_bInitialised;
+};
+
+#endif
diff --git a/kicker/kicker/ui/removeapplet_mnu.cpp b/kicker/kicker/ui/removeapplet_mnu.cpp
new file mode 100644
index 000000000..fce885f39
--- /dev/null
+++ b/kicker/kicker/ui/removeapplet_mnu.cpp
@@ -0,0 +1,99 @@
+/*****************************************************************
+
+Copyright (c) 2001 Matthias Elter <elter@kde.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#include <klocale.h>
+#include <kglobal.h>
+
+#include "pluginmanager.h"
+#include "containerarea.h"
+#include "container_applet.h"
+
+#include "panelmenuiteminfo.h"
+#include "removeapplet_mnu.h"
+#include "removeapplet_mnu.moc"
+
+PanelRemoveAppletMenu::PanelRemoveAppletMenu(ContainerArea* cArea,
+ QWidget *parent,
+ const char *name)
+ : QPopupMenu(parent, name), m_containerArea(cArea)
+{
+ connect(this, SIGNAL(activated(int)), SLOT(slotExec(int)));
+ connect(this, SIGNAL(aboutToShow()), SLOT(slotAboutToShow()));
+}
+
+void PanelRemoveAppletMenu::slotAboutToShow()
+{
+ int id = 0;
+
+ clear();
+ m_containers = m_containerArea->containers("Applet") +
+ m_containerArea->containers("Special Button");
+
+ QValueList<PanelMenuItemInfo> items;
+
+ for (BaseContainer::List::const_iterator it = m_containers.constBegin();
+ it != m_containers.constEnd();)
+ {
+ BaseContainer* container = *it;
+ if (container->isImmutable())
+ {
+ ++it;
+ m_containers.remove(container);
+ continue;
+ }
+
+ items.append(PanelMenuItemInfo(container->icon(),
+ container->visibleName().replace("&", "&&"),
+ id));
+ ++id;
+ ++it;
+ }
+
+ qHeapSort(items);
+
+ for (QValueList<PanelMenuItemInfo>::iterator it = items.begin();
+ it != items.end();
+ ++it)
+ {
+ (*it).plug(this);
+ }
+
+ if (m_containers.count() > 1)
+ {
+ insertSeparator();
+ insertItem(i18n("All"), this, SLOT(slotRemoveAll()), 0, id);
+ }
+}
+
+void PanelRemoveAppletMenu::slotExec(int id)
+{
+ if (m_containers.at(id) != m_containers.end())
+ {
+ m_containerArea->removeContainer(*m_containers.at(id));
+ }
+}
+
+void PanelRemoveAppletMenu::slotRemoveAll()
+{
+ m_containerArea->removeContainers(m_containers);
+}
diff --git a/kicker/kicker/ui/removeapplet_mnu.h b/kicker/kicker/ui/removeapplet_mnu.h
new file mode 100644
index 000000000..455a93afd
--- /dev/null
+++ b/kicker/kicker/ui/removeapplet_mnu.h
@@ -0,0 +1,52 @@
+/*****************************************************************
+
+Copyright (c) 2001 Matthias Elter <elter@kde.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#ifndef __removeapplet_mnu_h__
+#define __removeapplet_mnu_h__
+
+#include <qptrlist.h>
+#include <qpopupmenu.h>
+
+#include "appletinfo.h"
+#include "container_base.h"
+
+class ContainerArea;
+
+class PanelRemoveAppletMenu : public QPopupMenu
+{
+ Q_OBJECT
+
+public:
+ PanelRemoveAppletMenu(ContainerArea* cArea, QWidget* parent = 0, const char* name = 0);
+
+protected slots:
+ void slotExec( int id );
+ void slotAboutToShow();
+ void slotRemoveAll();
+
+private:
+ BaseContainer::List m_containers;
+ ContainerArea* m_containerArea;
+};
+
+#endif
diff --git a/kicker/kicker/ui/removebutton_mnu.cpp b/kicker/kicker/ui/removebutton_mnu.cpp
new file mode 100644
index 000000000..33dc48e14
--- /dev/null
+++ b/kicker/kicker/ui/removebutton_mnu.cpp
@@ -0,0 +1,111 @@
+/*****************************************************************
+
+Copyright (c) 2001 Matthias Elter <elter@kde.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#include <qregexp.h>
+#include <kiconloader.h>
+#include <klocale.h>
+#include <kglobal.h>
+#include <kdebug.h>
+
+#include "panelbutton.h"
+#include "pluginmanager.h"
+#include "containerarea.h"
+#include "container_button.h"
+
+#include "panelmenuiteminfo.h"
+#include "removebutton_mnu.h"
+#include "removebutton_mnu.moc"
+
+PanelRemoveButtonMenu::PanelRemoveButtonMenu( ContainerArea* cArea,
+ QWidget *parent, const char *name )
+ : QPopupMenu( parent, name ), containerArea( cArea )
+{
+ connect(this, SIGNAL(activated(int)), SLOT(slotExec(int)));
+ connect(this, SIGNAL(aboutToShow()), SLOT(slotAboutToShow()));
+}
+
+void PanelRemoveButtonMenu::addToContainers(const QString& type)
+{
+ BaseContainer::List list = containerArea->containers(type);
+ for (BaseContainer::Iterator it = list.begin();
+ it != list.end();
+ ++it)
+ {
+ if ((*it)->isImmutable())
+ {
+ continue;
+ }
+ containers.append(*it);
+ }
+}
+
+void PanelRemoveButtonMenu::slotAboutToShow()
+{
+ clear();
+ containers.clear();
+
+ addToContainers("URLButton");
+ addToContainers("ServiceButton");
+ addToContainers("ServiceMenuButton");
+ addToContainers("ExecButton");
+
+ int id = 0;
+ QValueList<PanelMenuItemInfo> items;
+ for (BaseContainer::Iterator it = containers.begin(); it != containers.end(); ++it)
+ {
+ items.append(PanelMenuItemInfo((*it)->icon(), (*it)->visibleName(), id));
+ id++;
+ }
+
+ qHeapSort(items);
+
+ for (QValueList<PanelMenuItemInfo>::iterator it = items.begin();
+ it != items.end();
+ ++it)
+ {
+ (*it).plug(this);
+ }
+
+ if (containers.count() > 1)
+ {
+ insertSeparator();
+ insertItem(i18n("All"), this, SLOT(slotRemoveAll()), 0, id);
+ }
+}
+
+void PanelRemoveButtonMenu::slotExec( int id )
+{
+ if (containers.at(id) != containers.end())
+ {
+ containerArea->removeContainer(*containers.at(id));
+ }
+}
+
+PanelRemoveButtonMenu::~PanelRemoveButtonMenu()
+{
+}
+
+void PanelRemoveButtonMenu::slotRemoveAll()
+{
+ containerArea->removeContainers(containers);
+}
diff --git a/kicker/kicker/ui/removebutton_mnu.h b/kicker/kicker/ui/removebutton_mnu.h
new file mode 100644
index 000000000..20d29c171
--- /dev/null
+++ b/kicker/kicker/ui/removebutton_mnu.h
@@ -0,0 +1,55 @@
+/*****************************************************************
+
+Copyright (c) 2001 Matthias Elter <elter@kde.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#ifndef __removebutton_mnu_h__
+#define __removebutton_mnu_h__
+
+#include <qptrlist.h>
+#include <qpopupmenu.h>
+
+#include "appletinfo.h"
+#include "container_base.h"
+
+class ContainerArea;
+
+class PanelRemoveButtonMenu : public QPopupMenu
+{
+ Q_OBJECT
+
+public:
+ PanelRemoveButtonMenu( ContainerArea *cArea, QWidget *parent=0, const char *name=0 );
+ ~PanelRemoveButtonMenu();
+
+protected slots:
+ void slotExec( int id );
+ void slotAboutToShow();
+ void slotRemoveAll();
+
+private:
+ void addToContainers(const QString& type);
+
+ BaseContainer::List containers;
+ ContainerArea* containerArea;
+};
+
+#endif
diff --git a/kicker/kicker/ui/removecontainer_mnu.cpp b/kicker/kicker/ui/removecontainer_mnu.cpp
new file mode 100644
index 000000000..ddce1f2df
--- /dev/null
+++ b/kicker/kicker/ui/removecontainer_mnu.cpp
@@ -0,0 +1,61 @@
+/*****************************************************************
+
+Copyreght (c) 2001 Matthias Elter <elter@kde.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#include <klocale.h>
+#include <kglobal.h>
+
+#include "removecontainer_mnu.h"
+#include "removecontainer_mnu.moc"
+
+#include "removeapplet_mnu.h"
+#include "removebutton_mnu.h"
+#include "removeextension_mnu.h"
+
+#include "kicker.h"
+#include "extensionmanager.h"
+#include "containerarea.h"
+
+RemoveContainerMenu::RemoveContainerMenu( ContainerArea* cArea,
+ QWidget *parent, const char *name)
+ : QPopupMenu( parent, name ), containerArea( cArea )
+{
+ appletId = insertItem(i18n("&Applet"),
+ new PanelRemoveAppletMenu(containerArea, this));
+ buttonId = insertItem(i18n("Appli&cation"),
+ new PanelRemoveButtonMenu( containerArea, this ) );
+ adjustSize();
+ connect( this, SIGNAL( aboutToShow() ), SLOT( slotAboutToShow() ) );
+}
+
+RemoveContainerMenu::~RemoveContainerMenu()
+{
+}
+
+void RemoveContainerMenu::slotAboutToShow()
+{
+ setItemEnabled(appletId, containerArea->containerCount("Applet") > 0 ||
+ containerArea->containerCount("Special Button") > 0);
+ setItemEnabled(buttonId, (containerArea->containerCount("ServiceMenuButton") +
+ containerArea->containerCount("ServiceButton")) > 0);
+}
+
diff --git a/kicker/kicker/ui/removecontainer_mnu.h b/kicker/kicker/ui/removecontainer_mnu.h
new file mode 100644
index 000000000..9d7142671
--- /dev/null
+++ b/kicker/kicker/ui/removecontainer_mnu.h
@@ -0,0 +1,47 @@
+/*****************************************************************
+
+Copyright (c) 2001 Matthias Elter <elter@kde.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#ifndef __removecontainer_mnu_h__
+#define __removecontainer_mnu_h__
+
+#include <qpopupmenu.h>
+
+class ContainerArea;
+
+class RemoveContainerMenu : public QPopupMenu
+{
+ Q_OBJECT
+
+public:
+ RemoveContainerMenu(ContainerArea* cArea, QWidget *parent=0, const char *name=0);
+ ~RemoveContainerMenu();
+
+protected slots:
+ void slotAboutToShow();
+
+private:
+ int appletId, buttonId;
+ ContainerArea *containerArea;
+};
+
+#endif
diff --git a/kicker/kicker/ui/removeextension_mnu.cpp b/kicker/kicker/ui/removeextension_mnu.cpp
new file mode 100644
index 000000000..7f7d09075
--- /dev/null
+++ b/kicker/kicker/ui/removeextension_mnu.cpp
@@ -0,0 +1,108 @@
+/*****************************************************************
+
+Copyright (c) 2001 Matthias Elter <elter@kde.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#include <klocale.h>
+#include <kglobal.h>
+
+#include "kicker.h"
+#include "extensionmanager.h"
+#include "pluginmanager.h"
+
+#include "panelmenuiteminfo.h"
+#include "removeextension_mnu.h"
+#include "removeextension_mnu.moc"
+
+static const int REMOVEALLID = 1000;
+
+PanelRemoveExtensionMenu::PanelRemoveExtensionMenu( QWidget *parent, const char *name )
+ : QPopupMenu( parent, name )
+{
+ connect(this, SIGNAL(activated(int)), SLOT(slotExec(int)));
+ connect(this, SIGNAL(aboutToShow()), SLOT(slotAboutToShow()));
+}
+
+PanelRemoveExtensionMenu::PanelRemoveExtensionMenu()
+{
+}
+
+void PanelRemoveExtensionMenu::slotAboutToShow()
+{
+ int id = 0;
+
+ clear();
+ m_containers = ExtensionManager::the()->containers();
+ QValueList<PanelMenuItemInfo> items;
+
+ ExtensionList::iterator itEnd = m_containers.end();
+ for (ExtensionList::iterator it = m_containers.begin(); it != itEnd; ++it)
+ {
+ const AppletInfo info = (*it)->info();
+ QString name = info.name().replace("&", "&&");
+ switch ((*it)->position())
+ {
+ case KPanelExtension::Top:
+ name = i18n("%1 (Top)").arg(name);
+ break;
+ case KPanelExtension::Right:
+ name = i18n("%1 (Right)").arg(name);
+ break;
+ case KPanelExtension::Bottom:
+ name = i18n("%1 (Bottom)").arg(name);
+ break;
+ case KPanelExtension::Left:
+ name = i18n("%1 (Left)").arg(name);
+ break;
+ case KPanelExtension::Floating:
+ name = i18n("%1 (Floating)").arg(name);
+ break;
+ }
+ items.append(PanelMenuItemInfo(QString::null, name, id));
+ ++id;
+ }
+
+ qHeapSort(items);
+ QValueList<PanelMenuItemInfo>::iterator itEnd2 = items.end();
+ for (QValueList<PanelMenuItemInfo>::iterator it = items.begin(); it != itEnd2; ++it)
+ {
+ (*it).plug(this);
+ }
+
+ if (m_containers.count() > 1)
+ {
+ insertSeparator();
+ insertItem(i18n("All"), REMOVEALLID);
+ }
+}
+
+void PanelRemoveExtensionMenu::slotExec( int id )
+{
+ if (id == REMOVEALLID)
+ {
+ ExtensionManager::the()->removeAllContainers();
+ }
+ else if (m_containers.at(id) != m_containers.end())
+ {
+ ExtensionManager::the()->removeContainer(*m_containers.at(id));
+ }
+}
+
diff --git a/kicker/kicker/ui/removeextension_mnu.h b/kicker/kicker/ui/removeextension_mnu.h
new file mode 100644
index 000000000..bc0e08b00
--- /dev/null
+++ b/kicker/kicker/ui/removeextension_mnu.h
@@ -0,0 +1,48 @@
+/*****************************************************************
+
+Copyright (c) 2001 Matthias Elter <elter@kde.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#ifndef __removeextension_mnu_h__
+#define __removeextension_mnu_h__
+
+#include <qptrlist.h>
+#include <qpopupmenu.h>
+
+#include "container_extension.h"
+
+class PanelRemoveExtensionMenu : public QPopupMenu
+{
+ Q_OBJECT
+
+public:
+ PanelRemoveExtensionMenu( QWidget *parent=0, const char *name=0 );
+ PanelRemoveExtensionMenu();
+
+protected slots:
+ void slotExec( int id );
+ void slotAboutToShow();
+
+private:
+ ExtensionList m_containers;
+};
+
+#endif
diff --git a/kicker/kicker/ui/service_mnu.cpp b/kicker/kicker/ui/service_mnu.cpp
new file mode 100644
index 000000000..a59c14ce8
--- /dev/null
+++ b/kicker/kicker/ui/service_mnu.cpp
@@ -0,0 +1,823 @@
+/*****************************************************************
+
+Copyright (c) 1996-2000 the kicker authors. See file AUTHORS.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#include <typeinfo>
+#include <qcursor.h>
+#include <qbitmap.h>
+#include <qpixmap.h>
+#include <qimage.h>
+
+#include <dcopclient.h>
+#include <kapplication.h>
+#include <kstandarddirs.h>
+#include <kdebug.h>
+#include <kdesktopfile.h>
+#include <kglobalsettings.h>
+#include <kiconloader.h>
+#include <klocale.h>
+#include <kmimetype.h>
+#include <kprocess.h>
+#include <krun.h>
+#include <kservicegroup.h>
+#include <ksycoca.h>
+#include <ksycocaentry.h>
+#include <kservice.h>
+#include <kurldrag.h>
+#include <kio/job.h>
+
+#include "global.h"
+#include "kicker.h"
+#include "kickerSettings.h"
+#include "menumanager.h"
+#include "popupmenutitle.h"
+#include "panelbutton.h"
+#include "recentapps.h"
+#include "service_mnu.h"
+#include "service_mnu.moc"
+
+PanelServiceMenu::PanelServiceMenu(const QString & label, const QString & relPath, QWidget * parent,
+ const char * name, bool addmenumode, const QString & insertInlineHeader)
+ : KPanelMenu(label, parent, name),
+ relPath_(relPath),
+ insertInlineHeader_( insertInlineHeader ),
+ clearOnClose_(false),
+ addmenumode_(addmenumode),
+ popupMenu_(0)
+{
+ excludeNoDisplay_=true;
+
+ connect(KSycoca::self(), SIGNAL(databaseChanged()),
+ SLOT(slotClearOnClose()));
+ connect(this, SIGNAL(aboutToHide()), this, SLOT(slotClose()));
+}
+
+PanelServiceMenu::~PanelServiceMenu()
+{
+ clearSubmenus();
+}
+
+
+void PanelServiceMenu::setExcludeNoDisplay( bool flag )
+{
+ excludeNoDisplay_=flag;
+}
+
+void PanelServiceMenu::showMenu()
+{
+ activateParent(QString::null);
+}
+
+// the initialization is split in initialize() and
+// doInitialize() so that a subclass does not have to
+// redo all the service parsing (see e.g. kicker/menuext/prefmenu)
+
+void PanelServiceMenu::initialize()
+{
+ if (initialized()) return;
+
+ setInitialized(true);
+ entryMap_.clear();
+ clear();
+
+ clearSubmenus();
+ doInitialize();
+}
+
+void PanelServiceMenu::fillMenu(KServiceGroup::Ptr& _root,
+ KServiceGroup::List& _list,
+ const QString& /* _relPath */,
+ int& id)
+{
+ QStringList suppressGenericNames = _root->suppressGenericNames();
+
+ KServiceGroup::List::ConstIterator it = _list.begin();
+ bool separatorNeeded = false;
+ for (; it != _list.end(); ++it)
+ {
+ KSycocaEntry * e = *it;
+
+ if (e->isType(KST_KServiceGroup))
+ {
+
+ KServiceGroup::Ptr g(static_cast<KServiceGroup *>(e));
+ QString groupCaption = g->caption();
+
+ // Avoid adding empty groups.
+ KServiceGroup::Ptr subMenuRoot = KServiceGroup::group(g->relPath());
+
+ int nbChildCount = subMenuRoot->childCount();
+ if (nbChildCount == 0 && !g->showEmptyMenu())
+ {
+ continue;
+ }
+
+ QString inlineHeaderName = g->showInlineHeader() ? groupCaption : "";
+ // Item names may contain ampersands. To avoid them being converted
+ // to accelerators, replace them with two ampersands.
+ groupCaption.replace("&", "&&");
+
+ if ( nbChildCount == 1 && g->allowInline() && g->inlineAlias())
+ {
+ KServiceGroup::Ptr element = KServiceGroup::group(g->relPath());
+ if ( element )
+ {
+ //just one element
+ KServiceGroup::List listElement = element->entries(true, excludeNoDisplay_, true, KickerSettings::menuEntryFormat() == KickerSettings::DescriptionAndName || KickerSettings::menuEntryFormat() == KickerSettings::DescriptionOnly);
+ KSycocaEntry * e1 = *( listElement.begin() );
+ if ( e1->isType( KST_KService ) )
+ {
+ if (separatorNeeded)
+ {
+ insertSeparator();
+ separatorNeeded = false;
+ }
+
+ KService::Ptr s(static_cast<KService *>(e1));
+ insertMenuItem(s, id++, -1, &suppressGenericNames);
+ continue;
+ }
+ }
+ }
+
+ if (g->allowInline() && ((nbChildCount <= g->inlineValue() ) || (g->inlineValue() == 0)))
+ {
+ //inline all entries
+ KServiceGroup::Ptr rootElement = KServiceGroup::group(g->relPath());
+
+ if (!rootElement || !rootElement->isValid())
+ {
+ break;
+ }
+
+ KServiceGroup::List listElement = rootElement->entries(true, excludeNoDisplay_, true, KickerSettings::menuEntryFormat() == KickerSettings::DescriptionAndName || KickerSettings::menuEntryFormat() == KickerSettings::DescriptionOnly);
+
+ if ( !g->inlineAlias() && !inlineHeaderName.isEmpty() )
+ {
+ int mid = insertItem(new PopupMenuTitle(inlineHeaderName, font()), id + 1, id);
+ id++;
+ setItemEnabled( mid, false );
+ }
+
+ fillMenu( rootElement, listElement, g->relPath(), id );
+ continue;
+ }
+
+ // Ignore dotfiles.
+ if ((g->name().at(0) == '.'))
+ {
+ continue;
+ }
+
+ PanelServiceMenu * m =
+ newSubMenu(g->name(), g->relPath(), this, g->name().utf8(), inlineHeaderName);
+ m->setCaption(groupCaption);
+
+ QIconSet iconset = KickerLib::menuIconSet(g->icon());
+
+ if (separatorNeeded)
+ {
+ insertSeparator();
+ separatorNeeded = false;
+ }
+
+ int newId = insertItem(iconset, groupCaption, m, id++);
+ entryMap_.insert(newId, static_cast<KSycocaEntry*>(g));
+ // We have to delete the sub menu our selves! (See Qt docs.)
+ subMenus.append(m);
+ }
+ else if (e->isType(KST_KService))
+ {
+ if (separatorNeeded)
+ {
+ insertSeparator();
+ separatorNeeded = false;
+ }
+
+ KService::Ptr s(static_cast<KService *>(e));
+ insertMenuItem(s, id++, -1, &suppressGenericNames);
+ }
+ else if (e->isType(KST_KServiceSeparator))
+ {
+ separatorNeeded = true;
+ }
+ }
+#if 0
+ // WABA: tear off handles don't work together with dynamically updated
+ // menus. We can't update the menu while torn off, and we don't know
+ // when it is torn off.
+ if ( count() > 0 && !relPath_.isEmpty() )
+ if (KGlobalSettings::insertTearOffHandle())
+ insertTearOffHandle();
+#endif
+}
+
+void PanelServiceMenu::clearSubmenus()
+{
+ for (PopupMenuList::const_iterator it = subMenus.constBegin();
+ it != subMenus.constEnd();
+ ++it)
+ {
+ delete *it;
+ }
+ subMenus.clear();
+}
+
+void PanelServiceMenu::doInitialize()
+{
+
+ // Set the startposition outside the panel, so there is no drag initiated
+ // when we use drag and click to select items. A drag is only initiated when
+ // you click to open the menu, and then press and drag an item.
+ startPos_ = QPoint(-1,-1);
+
+ // We ask KSycoca to give us all services (sorted).
+ KServiceGroup::Ptr root = KServiceGroup::group(relPath_);
+
+ if (!root || !root->isValid())
+ return;
+
+ KServiceGroup::List list = root->entries(true, excludeNoDisplay_, true, KickerSettings::menuEntryFormat() == KickerSettings::DescriptionAndName || KickerSettings::menuEntryFormat() == KickerSettings::DescriptionOnly);
+
+ if (list.isEmpty()) {
+ setItemEnabled(insertItem(i18n("No Entries")), false);
+ return;
+ }
+
+ int id = serviceMenuStartId();
+
+ if (addmenumode_) {
+ int mid = insertItem(KickerLib::menuIconSet("ok"), i18n("Add This Menu"), id++);
+ entryMap_.insert(mid, static_cast<KSycocaEntry*>(root));
+
+ if (relPath_ == "")
+ {
+ insertItem(KickerLib::menuIconSet("exec"), i18n("Add Non-KDE Application"),
+ this, SLOT(addNonKDEApp()));
+ }
+
+ if (list.count() > 0) {
+ insertSeparator();
+ id++;
+ }
+ }
+ if ( !insertInlineHeader_.isEmpty() )
+ {
+ int mid = insertItem(new PopupMenuTitle(insertInlineHeader_, font()), -1, 0);
+ setItemEnabled( mid, false );
+ }
+ fillMenu( root, list, relPath_, id );
+}
+
+void PanelServiceMenu::configChanged()
+{
+ deinitialize();
+}
+
+void PanelServiceMenu::insertMenuItem(KService::Ptr & s, int nId,
+ int nIndex/*= -1*/,
+ const QStringList *suppressGenericNames /* = 0 */,
+ const QString & aliasname)
+{
+ QString serviceName = (aliasname.isEmpty() ? s->name() : aliasname).simplifyWhiteSpace();
+ QString comment = s->genericName().simplifyWhiteSpace();
+
+ if (!comment.isEmpty())
+ {
+ if (KickerSettings::menuEntryFormat() == KickerSettings::NameAndDescription)
+ {
+ if ((!suppressGenericNames ||
+ !suppressGenericNames->contains(s->untranslatedGenericName())) &&
+ serviceName.find(comment, 0, true) == -1)
+ {
+ if (comment.find(serviceName, 0, true) == -1)
+ {
+ serviceName = i18n("Entries in K-menu: %1 app name, %2 description", "%1 - %2").arg(serviceName, comment);
+ }
+ else
+ {
+ serviceName = comment;
+ }
+ }
+ }
+ else if (KickerSettings::menuEntryFormat() == KickerSettings::DescriptionAndName)
+ {
+ serviceName = i18n("Entries in K-menu: %1 description, %2 app name", "%1 (%2)").arg(comment, serviceName);
+ }
+ else if (KickerSettings::menuEntryFormat() == KickerSettings::DescriptionOnly)
+ {
+ serviceName = comment;
+ }
+ }
+
+ // restrict menu entries to a sane length
+ if ( serviceName.length() > 60 ) {
+ serviceName.truncate( 57 );
+ serviceName += "...";
+ }
+
+ // check for NoDisplay
+ if (s->noDisplay())
+ return;
+
+ // ignore dotfiles.
+ if ((serviceName.at(0) == '.'))
+ return;
+
+ // item names may contain ampersands. To avoid them being converted
+ // to accelerators, replace them with two ampersands.
+ serviceName.replace("&", "&&");
+
+ int newId = insertItem(KickerLib::menuIconSet(s->icon()), serviceName, nId, nIndex);
+ entryMap_.insert(newId, static_cast<KSycocaEntry*>(s));
+}
+
+void PanelServiceMenu::activateParent(const QString &child)
+{
+ PanelServiceMenu *parentMenu = dynamic_cast<PanelServiceMenu*>(parent());
+ if (parentMenu)
+ {
+ parentMenu->activateParent(relPath_);
+ }
+ else
+ {
+ PanelPopupButton *kButton = MenuManager::the()->findKButtonFor(this);
+ if (kButton)
+ {
+ adjustSize();
+ kButton->showMenu();
+ }
+ else
+ {
+ show();
+ }
+ }
+
+ if (!child.isEmpty())
+ {
+ EntryMap::Iterator mapIt;
+ for ( mapIt = entryMap_.begin(); mapIt != entryMap_.end(); ++mapIt )
+ {
+ KServiceGroup *g = dynamic_cast<KServiceGroup *>(static_cast<KSycocaEntry*>(mapIt.data()));
+
+ // if the dynamic_cast fails, we are looking at a KService entry
+ if (g && (g->relPath() == child))
+ {
+ activateItemAt(indexOf(mapIt.key()));
+ return;
+ }
+ }
+ }
+}
+
+bool PanelServiceMenu::highlightMenuItem( const QString &menuItemId )
+{
+ initialize();
+
+ // Check menu itself
+ EntryMap::Iterator mapIt;
+ for ( mapIt = entryMap_.begin(); mapIt != entryMap_.end(); ++mapIt )
+ {
+ // Skip recent files menu
+ if (mapIt.key() >= serviceMenuEndId())
+ {
+ continue;
+ }
+ KService *s = dynamic_cast<KService *>(
+ static_cast<KSycocaEntry*>(mapIt.data()));
+ if (s && (s->menuId() == menuItemId))
+ {
+ activateParent(QString::null);
+ int index = indexOf(mapIt.key());
+ setActiveItem(index);
+
+ // Warp mouse pointer to location of active item
+ QRect r = itemGeometry(index);
+ QCursor::setPos(mapToGlobal(QPoint(r.x()+ r.width() - 15,
+ r.y() + r.height() - 5)));
+ return true;
+ }
+ }
+
+ for(PopupMenuList::iterator it = subMenus.begin();
+ it != subMenus.end();
+ ++it)
+ {
+ PanelServiceMenu *serviceMenu = dynamic_cast<PanelServiceMenu*>(*it);
+ if (serviceMenu && serviceMenu->highlightMenuItem(menuItemId))
+ return true;
+ }
+ return false;
+}
+
+void PanelServiceMenu::slotExec(int id)
+{
+ if (!entryMap_.contains(id))
+ {
+ return;
+ }
+
+ KSycocaEntry * e = entryMap_[id];
+
+ kapp->propagateSessionManager();
+
+ KService::Ptr service = static_cast<KService *>(e);
+ KApplication::startServiceByDesktopPath(service->desktopEntryPath(),
+ QStringList(), 0, 0, 0, "", true);
+
+ updateRecentlyUsedApps(service);
+ startPos_ = QPoint(-1,-1);
+}
+
+void PanelServiceMenu::mousePressEvent(QMouseEvent * ev)
+{
+ startPos_ = ev->pos();
+ KPanelMenu::mousePressEvent(ev);
+}
+
+void PanelServiceMenu::mouseReleaseEvent(QMouseEvent * ev)
+{
+ if (ev->button() == RightButton && !Kicker::the()->isKioskImmutable())
+ {
+ int id = idAt( ev->pos() );
+
+ if (id < serviceMenuStartId())
+ {
+ return;
+ }
+
+ if (!entryMap_.contains(id))
+ {
+ kdDebug(1210) << "Cannot find service with menu id " << id << endl;
+ return;
+ }
+
+ contextKSycocaEntry_ = entryMap_[id];
+
+ delete popupMenu_;
+ popupMenu_ = new KPopupMenu(this);
+ connect(popupMenu_, SIGNAL(activated(int)), SLOT(slotContextMenu(int)));
+ bool hasEntries = false;
+
+ switch (contextKSycocaEntry_->sycocaType())
+ {
+ case KST_KService:
+ if (kapp->authorize("editable_desktop_icons"))
+ {
+ hasEntries = true;
+ popupMenu_->insertItem(SmallIconSet("desktop"),
+ i18n("Add Item to Desktop"), AddItemToDesktop);
+ }
+ if (kapp->authorizeKAction("kicker_rmb") && !Kicker::the()->isImmutable())
+ {
+ hasEntries = true;
+ popupMenu_->insertItem(SmallIconSet("kicker"),
+ i18n("Add Item to Main Panel"), AddItemToPanel);
+ }
+ if (kapp->authorizeKAction("menuedit"))
+ {
+ hasEntries = true;
+ popupMenu_->insertItem(SmallIconSet("kmenuedit"),
+ i18n("Edit Item"), EditItem);
+ }
+ if (kapp->authorize("run_command"))
+ {
+ hasEntries = true;
+ popupMenu_->insertItem(SmallIconSet("run"),
+ i18n("Put Into Run Dialog"), PutIntoRunDialog);
+ }
+ break;
+
+ case KST_KServiceGroup:
+ if (kapp->authorize("editable_desktop_icons"))
+ {
+ hasEntries = true;
+ popupMenu_->insertItem(SmallIconSet("desktop"),
+ i18n("Add Menu to Desktop"), AddMenuToDesktop);
+ }
+ if (kapp->authorizeKAction("kicker_rmb") && !Kicker::the()->isImmutable())
+ {
+ hasEntries = true;
+ popupMenu_->insertItem(SmallIconSet("kicker"),
+ i18n("Add Menu to Main Panel"), AddMenuToPanel);
+ }
+ if (kapp->authorizeKAction("menuedit"))
+ {
+ hasEntries = true;
+ popupMenu_->insertItem(SmallIconSet("kmenuedit"),
+ i18n("Edit Menu"), EditMenu);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (hasEntries)
+ {
+ popupMenu_->popup(this->mapToGlobal(ev->pos()));
+ return;
+ }
+ }
+
+ delete popupMenu_;
+ popupMenu_ = 0;
+
+ KPanelMenu::mouseReleaseEvent(ev);
+}
+
+extern int kicker_screen_number;
+
+void PanelServiceMenu::slotContextMenu(int selected)
+{
+ KProcess *proc;
+ KService::Ptr service;
+ KServiceGroup::Ptr g;
+ QByteArray ba;
+ QDataStream ds(ba, IO_WriteOnly);
+
+ KURL src,dest;
+ KIO::CopyJob *job;
+ KDesktopFile *df;
+
+ switch (selected) {
+ case AddItemToDesktop:
+ service = static_cast<KService *>(contextKSycocaEntry_);
+
+ src.setPath( KGlobal::dirs()->findResource( "apps", service->desktopEntryPath() ) );
+ dest.setPath( KGlobalSettings::desktopPath() );
+ dest.setFileName( src.fileName() );
+
+ job = KIO::copyAs( src, dest );
+ job->setDefaultPermissions( true );
+ break;
+
+ case AddItemToPanel: {
+ QCString appname = "kicker";
+ if ( kicker_screen_number )
+ appname.sprintf("kicker-screen-%d", kicker_screen_number);
+ service = static_cast<KService *>(contextKSycocaEntry_);
+ kapp->dcopClient()->send(appname, "Panel", "addServiceButton(QString)", service->desktopEntryPath());
+ break;
+ }
+
+ case EditItem:
+ proc = new KProcess(this);
+ *proc << KStandardDirs::findExe(QString::fromLatin1("kmenuedit"));
+ *proc << "/"+relPath_ << static_cast<KService *>(contextKSycocaEntry_)->menuId();
+ proc->start();
+ break;
+
+ case PutIntoRunDialog: {
+ close();
+ QCString appname = "kdesktop";
+ if ( kicker_screen_number )
+ appname.sprintf("kdesktop-screen-%d", kicker_screen_number);
+ service = static_cast<KService *>(contextKSycocaEntry_);
+ kapp->updateRemoteUserTimestamp( appname );
+ kapp->dcopClient()->send(appname, "default", "popupExecuteCommand(QString)", service->exec());
+ break;
+ }
+
+ case AddMenuToDesktop:
+ g = static_cast<KServiceGroup *>(contextKSycocaEntry_);
+ dest.setPath( KGlobalSettings::desktopPath() );
+ dest.setFileName( g->caption() );
+
+ df = new KDesktopFile( dest.path() );
+ df->writeEntry( "Icon", g->icon() );
+ df->writePathEntry( "URL", "programs:/"+g->name() );
+ df->writeEntry( "Name", g->caption() );
+ df->writeEntry( "Type", "Link" );
+ df->sync();
+ delete df;
+
+ break;
+
+ case AddMenuToPanel: {
+ QCString appname = "kicker";
+ if ( kicker_screen_number )
+ appname.sprintf("kicker-screen-%d", kicker_screen_number);
+
+ g = static_cast<KServiceGroup *>(contextKSycocaEntry_);
+ ds << "foo" << g->relPath();
+ kapp->dcopClient()->send("kicker", "Panel", "addServiceMenuButton(QString,QString)", ba);
+ break;
+ }
+
+ case EditMenu:
+ proc = new KProcess(this);
+ *proc << KStandardDirs::findExe(QString::fromLatin1("kmenuedit"));
+ *proc << "/"+static_cast<KServiceGroup *>(contextKSycocaEntry_)->relPath();
+ proc->start();
+ break;
+
+ default:
+ break;
+ }
+}
+
+void PanelServiceMenu::mouseMoveEvent(QMouseEvent * ev)
+{
+ KPanelMenu::mouseMoveEvent(ev);
+
+ if (Kicker::the()->isKioskImmutable())
+ return;
+
+ if ( (ev->state() & LeftButton ) != LeftButton )
+ return;
+
+ QPoint p = ev->pos() - startPos_;
+ if (p.manhattanLength() <= QApplication::startDragDistance() )
+ return;
+
+ int id = idAt(startPos_);
+
+ // Don't drag items we didn't create.
+ if (id < serviceMenuStartId())
+ return;
+
+ if (!entryMap_.contains(id)) {
+ kdDebug(1210) << "Cannot find service with menu id " << id << endl;
+ return;
+ }
+
+ KSycocaEntry * e = entryMap_[id];
+
+ QPixmap icon;
+ KURL url;
+
+ switch (e->sycocaType()) {
+
+ case KST_KService:
+ {
+ icon = static_cast<KService *>(e)->pixmap(KIcon::Small);
+ QString filePath = static_cast<KService *>(e)->desktopEntryPath();
+ if (filePath[0] != '/')
+ {
+ filePath = locate("apps", filePath);
+ }
+ url.setPath(filePath);
+ break;
+ }
+
+ case KST_KServiceGroup:
+ {
+ icon = KGlobal::iconLoader()
+ ->loadIcon(static_cast<KServiceGroup *>(e)->icon(), KIcon::Small);
+ url = "programs:/" + static_cast<KServiceGroup *>(e)->relPath();
+ break;
+ }
+
+ default:
+ {
+ return;
+ break;
+ }
+ }
+
+ // If the path to the desktop file is relative, try to get the full
+ // path from KStdDirs.
+
+ KURLDrag *d = new KURLDrag(KURL::List(url), this);
+ connect(d, SIGNAL(destroyed()), this, SLOT(slotDragObjectDestroyed()));
+ d->setPixmap(icon);
+ d->dragCopy();
+
+ // Set the startposition outside the panel, so there is no drag initiated
+ // when we use drag and click to select items. A drag is only initiated when
+ // you click to open the menu, and then press and drag an item.
+ startPos_ = QPoint(-1,-1);
+}
+
+void PanelServiceMenu::dragEnterEvent(QDragEnterEvent *event)
+{
+ // Set the DragObject's target to this widget. This is needed because the
+ // widget doesn't accept drops, but we want to determine if the drag object
+ // is dropped on it. This avoids closing on accidental drags. If this
+ // widget accepts drops in the future, these lines can be removed.
+ if (event->source() == this)
+ {
+ KURLDrag::setTarget(this);
+ }
+ event->ignore();
+}
+
+void PanelServiceMenu::dragLeaveEvent(QDragLeaveEvent *)
+{
+ // see PanelServiceMenu::dragEnterEvent why this is nescessary
+ if (!frameGeometry().contains(QCursor::pos()))
+ {
+ KURLDrag::setTarget(0);
+ }
+}
+
+void PanelServiceMenu::slotDragObjectDestroyed()
+{
+ if (KURLDrag::target() != this)
+ {
+ // we need to re-enter the event loop before calling close() here
+ // this gets called _before_ the drag object is destroyed, so we are
+ // still in its event loop. closing the menu before that event loop is
+ // exited may result in getting hung up in it which in turn prevents
+ // the execution of any code after the original exec() statement
+ // though the panels themselves continue on otherwise normally
+ // (we just have some sort of nested event loop)
+ QTimer::singleShot(0, this, SLOT(close()));
+ }
+}
+
+PanelServiceMenu *PanelServiceMenu::newSubMenu(const QString & label, const QString & relPath,
+ QWidget * parent, const char * name, const QString& _inlineHeader)
+{
+ return new PanelServiceMenu(label, relPath, parent, name, false,_inlineHeader);
+}
+
+void PanelServiceMenu::slotClearOnClose()
+{
+ if (!initialized()) return;
+
+ if (!isVisible()){
+ clearOnClose_ = false;
+ slotClear();
+ } else {
+ clearOnClose_ = true;
+ }
+}
+
+void PanelServiceMenu::slotClose()
+{
+ if (clearOnClose_)
+ {
+ clearOnClose_ = false;
+ slotClear();
+ }
+
+ delete popupMenu_;
+ popupMenu_ = 0;
+}
+
+void PanelServiceMenu::slotClear()
+{
+ if (isVisible())
+ {
+ // QPopupMenu's aboutToHide() is emitted before the popup is really hidden,
+ // and also before a click in the menu is handled, so do the clearing
+ // only after that has been handled
+ QTimer::singleShot(100, this, SLOT(slotClear()));
+ return;
+ }
+
+ entryMap_.clear();
+ KPanelMenu::slotClear();
+
+ for (PopupMenuList::iterator it = subMenus.begin();
+ it != subMenus.end();
+ ++it)
+ {
+ delete *it;
+ }
+ subMenus.clear();
+}
+
+void PanelServiceMenu::selectFirstItem()
+{
+ setActiveItem(indexOf(serviceMenuStartId()));
+}
+
+// updates "recent" section of KMenu
+void PanelServiceMenu::updateRecentlyUsedApps(KService::Ptr &service)
+{
+ QString strItem(service->desktopEntryPath());
+
+ // don't add an item from root kmenu level
+ if (!strItem.contains('/'))
+ {
+ return;
+ }
+
+ // add it into recent apps list
+ RecentlyLaunchedApps::the().appLaunched(strItem);
+ RecentlyLaunchedApps::the().save();
+ RecentlyLaunchedApps::the().m_bNeedToUpdate = true;
+}
+
diff --git a/kicker/kicker/ui/service_mnu.h b/kicker/kicker/ui/service_mnu.h
new file mode 100644
index 000000000..9e28acd3f
--- /dev/null
+++ b/kicker/kicker/ui/service_mnu.h
@@ -0,0 +1,129 @@
+/*****************************************************************
+
+Copyright (c) 1996-2000 the kicker authors. See file AUTHORS.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#ifndef SERVICE_MENU_H
+#define SERVICE_MENU_H
+
+#include <qmap.h>
+#include <qvaluevector.h>
+
+#include <ksycocaentry.h>
+#include <kservice.h>
+#include <kpanelmenu.h>
+#include <kservicegroup.h>
+/**
+ * PanelServiceMenu is filled with KDE services and service groups. The sycoca
+ * database is queried and the hierarchical structure built by creating child
+ * menus of type PanelServiceMenu, so the creation is recursive.
+ *
+ * The entries are sorted alphabetically and groups come before services.
+ *
+ * @author Rik Hemsley <rik@kde.org>
+ */
+
+typedef QMap<int, KSycocaEntry::Ptr> EntryMap;
+typedef QValueVector<QPopupMenu*> PopupMenuList;
+
+class KDE_EXPORT PanelServiceMenu : public KPanelMenu
+{
+ Q_OBJECT
+
+public:
+ PanelServiceMenu(const QString & label, const QString & relPath,
+ QWidget* parent = 0, const char* name = 0,
+ bool addmenumode = false,
+ const QString &insertInlineHeader = QString::null);
+
+ virtual ~PanelServiceMenu();
+
+ QString relPath() { return relPath_; }
+
+ void setExcludeNoDisplay( bool flag );
+
+ virtual void showMenu();
+ bool highlightMenuItem( const QString &menuId );
+ void selectFirstItem();
+
+private:
+ void fillMenu( KServiceGroup::Ptr &_root, KServiceGroup::List &_list,
+ const QString &_relPath, int & id );
+
+protected slots:
+ virtual void initialize();
+ virtual void slotExec(int id);
+ virtual void slotClearOnClose();
+ virtual void slotClear();
+ virtual void configChanged();
+ virtual void slotClose();
+ void slotDragObjectDestroyed();
+
+ // for use in Add Applicaton To Panel
+ virtual void addNonKDEApp() {}
+
+protected:
+ void insertMenuItem(KService::Ptr & s, int nId, int nIndex = -1,
+ const QStringList *suppressGenericNames=0,
+ const QString &aliasname = QString::null);
+ virtual PanelServiceMenu * newSubMenu(const QString & label,
+ const QString & relPath,
+ QWidget * parent, const char * name,
+ const QString & _inlineHeader =
+ QString::null);
+
+ virtual void mousePressEvent(QMouseEvent *);
+ virtual void mouseReleaseEvent(QMouseEvent *);
+ virtual void mouseMoveEvent(QMouseEvent *);
+ virtual void dragEnterEvent(QDragEnterEvent *);
+ virtual void dragLeaveEvent(QDragLeaveEvent *);
+ virtual void updateRecentlyUsedApps(KService::Ptr &s);
+ void activateParent(const QString &child);
+ int serviceMenuStartId() { return 4242; }
+ int serviceMenuEndId() { return 5242; }
+ virtual void clearSubmenus();
+ void doInitialize();
+
+ QString relPath_;
+
+ EntryMap entryMap_;
+
+ bool loaded_;
+ bool excludeNoDisplay_;
+ QString insertInlineHeader_;
+ QPopupMenu * opPopup_;
+ bool clearOnClose_;
+ bool addmenumode_;
+ QPoint startPos_;
+ PopupMenuList subMenus;
+
+private slots:
+ void slotContextMenu(int);
+
+private:
+ enum ContextMenuEntry { AddItemToPanel, EditItem, AddMenuToPanel, EditMenu,
+ AddItemToDesktop, AddMenuToDesktop, PutIntoRunDialog };
+ KPopupMenu* popupMenu_;
+ KSycocaEntry* contextKSycocaEntry_;
+ void readConfig();
+ };
+
+#endif // SERVICE_MENU_H