diff options
author | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
---|---|---|
committer | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
commit | 4aed2c8219774f5d797760606b8489a92ddc5163 (patch) | |
tree | 3f8c130f7d269626bf6a9447407ef6c35954426a /kicker/kicker/ui | |
download | tdebase-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')
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>&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><qt>Type here some text to filter on the applet names and comments</qt></string> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>S&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><qt>Select here the only applet category that you want to show</qt></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><qt>This is the applet list. Select an applet and click on <b>Add to panel</b> to add it</qt></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>&Add to Panel</string> + </property> + </widget> + <widget class="KPushButton"> + <property name="name"> + <cstring>closeButton</cstring> + </property> + <property name="text"> + <string>&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&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. + +<i>Example</i>: 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 &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. + +<i>Example</i>: 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>&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>&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>&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 |