From 21fcfa3348213aa87f0e3aef62ca4720c6d31cb7 Mon Sep 17 00:00:00 2001 From: Robert Xu Date: Thu, 10 Nov 2011 18:04:39 -0500 Subject: initial commit to suse branch: eclipse integration --- opensuse/core/tdebase/kickoff.diff | 9812 ++++++++++++++++++++++++++++++++++++ 1 file changed, 9812 insertions(+) create mode 100644 opensuse/core/tdebase/kickoff.diff (limited to 'opensuse/core/tdebase/kickoff.diff') diff --git a/opensuse/core/tdebase/kickoff.diff b/opensuse/core/tdebase/kickoff.diff new file mode 100644 index 000000000..e2d73f567 --- /dev/null +++ b/opensuse/core/tdebase/kickoff.diff @@ -0,0 +1,9812 @@ +--- taskbar/taskcontainer.cpp (Revision 849788) ++++ taskbar/taskcontainer.cpp (Revision 849791) +@@ -67,7 +67,11 @@ + discardNextMouseEvent(false), + aboutToActivate(false), + m_mouseOver(false), +- m_paintEventCompression(false) ++ animationTimer(0, "TaskContainer::animationTimer"), ++ dragSwitchTimer(0, "TaskContainer::dragSwitchTimer"), ++ attentionTimer(0, "TaskContainer::attentionTimer"), ++ m_paintEventCompression(false), ++ m_paintEventCompressionTimer(0, "TaskContainer::paintEventCompressionTimer") + { + init(); + setAcceptDrops(true); // Always enabled to activate task during drag&drop. +@@ -95,7 +99,11 @@ + discardNextMouseEvent(false), + aboutToActivate(false), + m_mouseOver(false), +- m_paintEventCompression(false) ++ animationTimer(0, "TaskContainer::animationTimer"), ++ dragSwitchTimer(0, "TaskContainer::dragSwitchTimer"), ++ attentionTimer(0, "TaskContainer::attentionTimer"), ++ m_paintEventCompression(false), ++ m_paintEventCompressionTimer(0, "TaskContainer::paintEventCompressionTimer") + { + init(); + setEnabled(false); +--- taskbar/taskbar.cpp 2009/11/20 21:00:26 1.1 ++++ taskbar/taskbar.cpp 2009/11/20 21:00:38 +@@ -59,7 +59,8 @@ + m_showIcon(false), + m_showOnlyIconified(false), + m_textShadowEngine(0), +- m_ignoreUpdates(false) ++ m_ignoreUpdates(false), ++ m_relayoutTimer(0, "TaskBar::m_relayoutTimer") + { + arrowType = LeftArrow; + blocklayout = true; +--- libkicker/panelbutton.h (Revision 849788) ++++ libkicker/panelbutton.h (Revision 849791) +@@ -254,9 +254,11 @@ + /** + * Sets the direction to pop up the contents of the button. + */ +- void setPopupDirection(KPanelApplet::Direction d); ++ virtual void setPopupDirection(KPanelApplet::Direction d); + + protected: ++ ++ void setIconAlignment(AlignmentFlags align); + /** + * Subclasses must implement this to define the name of the button which is + * used to identify this button for saving and loading. It must be unique +@@ -391,6 +393,7 @@ + QPixmap m_iconz; // mouse over + KPanelExtension::Position m_arrowDirection; + KPanelApplet::Direction m_popupDirection; ++ AlignmentFlags m_iconAlignment; + Orientation m_orientation; + int m_size; + double m_fontPercent; +@@ -419,12 +422,12 @@ + * Sets the button's popup menu. + * @param popup the menu to pop up + */ +- void setPopup(QPopupMenu *popup); ++ void setPopup(QWidget *popup); + + /** + * @return the button's popup menu + */ +- QPopupMenu *popup() const; ++ QWidget *popup() const; + + bool eventFilter(QObject *, QEvent *); + virtual void showMenu(); +@@ -459,8 +462,8 @@ + private slots: + void menuAboutToHide(); + +-private: +- QPopupMenu *m_popup; ++protected: ++ QWidget *m_popup; + bool m_pressedDuringPopup; + bool m_initialized; + +--- libkicker/kickerSettings.kcfg (Revision 849788) ++++ libkicker/kickerSettings.kcfg (Revision 849791) +@@ -98,6 +98,70 @@ + + + ++ ++ ++ false ++ ++ ++ ++ ++ true ++ ++ ++ ++ ++ true ++ ++ ++ ++ ++ 0 ++ ++ ++ ++ ++ 0 ++ ++ ++ ++ ++ 0 ++ -100 ++ 100 ++ ++ ++ ++ ++ false ++ ++ ++ ++ ++ false ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ LabelAndIcon ++ ++ ++ ++ ++ ++ true ++ ++ ++ + + + +@@ -172,6 +236,19 @@ + false + + ++ ++ ++ ++ ++ ++ ++ false ++ ++ ++ ++ ++ ++ + + + +@@ -337,6 +414,29 @@ + + + ++ ++ ++ ++ ++ ++ ++ ++ 50 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ 2 ++ ++ ++ ++ ++ + + + +--- libkicker/kickertip.cpp (Revision 849788) ++++ libkicker/kickertip.cpp (Revision 849791) +@@ -38,6 +38,7 @@ + + // putting this #include higher results in compile errors + #include ++#include + + static const int DEFAULT_FRAMES_PER_SECOND = 30; + +@@ -71,14 +72,16 @@ + m_dissolveDelta(-1), + m_direction(KPanelApplet::Up), + m_dirty(false), +- m_toolTipsEnabled(KickerSettings::showToolTips()), +- m_tippingFor(0) ++ m_tippingFor(0), ++ m_timer(0, "KickerTip::m_timer"), ++ m_frameTimer(0, "KickerTip::m_frameTimer") + { + setFocusPolicy(NoFocus); + setBackgroundMode(NoBackground); + resize(0, 0); + hide(); + connect(&m_frameTimer, SIGNAL(timeout()), SLOT(internalUpdate())); ++ connect(kapp, SIGNAL(settingsChanged(SettingsCategory)), SLOT(slotSettingsChanged())); + } + + KickerTip::~KickerTip() +@@ -87,6 +90,11 @@ + delete m_mimeFactory; + } + ++void KickerTip::slotSettingsChanged() ++{ ++ QToolTip::setGloballyEnabled(KickerSettings::showToolTips()); ++} ++ + void KickerTip::display() + { + if (!tippingEnabled()) +@@ -192,9 +200,7 @@ + + void KickerTip::mousePressEvent(QMouseEvent * /*e*/) + { +- QToolTip::setGloballyEnabled(m_toolTipsEnabled); + m_timer.stop(); +- m_frameTimer.stop(); + hide(); + } + +@@ -395,8 +401,11 @@ + m_tippingEnabled--; + } + ++ assert(m_tippingEnabled >= -1); ++ + if (m_tippingEnabled < 1 && m_self) + { ++ m_self->m_timer.stop(); + m_self->hide(); + } + } +@@ -411,6 +420,8 @@ + m_tippingFor = 0; + m_frameTimer.stop(); + QWidget::hide(); ++ ++ QToolTip::setGloballyEnabled(KickerSettings::showToolTips()); + } + + bool KickerTip::eventFilter(QObject *object, QEvent *event) +@@ -439,7 +450,6 @@ + !qApp->activePopupWidget() && + !isTippingFor(widget)) + { +- m_toolTipsEnabled = QToolTip::isGloballyEnabled(); + QToolTip::setGloballyEnabled(false); + + tipFor(widget); +@@ -461,8 +471,6 @@ + } + break; + case QEvent::Leave: +- QToolTip::setGloballyEnabled(m_toolTipsEnabled); +- + m_timer.stop(); + + if (isTippingFor(widget) && isVisible()) +@@ -475,9 +483,7 @@ + tipFor(0); + break; + case QEvent::MouseButtonPress: +- QToolTip::setGloballyEnabled(m_toolTipsEnabled); + m_timer.stop(); +- m_frameTimer.stop(); + hide(); + default: + break; +--- libkicker/kickertip.h (Revision 849788) ++++ libkicker/kickertip.h (Revision 849791) +@@ -92,6 +92,7 @@ + void tipperDestroyed(QObject* o); + void internalUpdate(); + void display(); ++ void slotSettingsChanged(); + + private: + QBitmap m_mask; +@@ -108,7 +109,6 @@ + QTimer m_timer; + QTimer m_frameTimer; + bool m_dirty; +- bool m_toolTipsEnabled; + + const QWidget* m_tippingFor; + +--- libkicker/panelbutton.cpp (Revision 849788) ++++ libkicker/panelbutton.cpp (Revision 849791) +@@ -42,6 +42,7 @@ + #include + #include + #include ++#include + + #include "global.h" + +@@ -65,6 +66,7 @@ + m_hasAcceptedDrag(false), + m_arrowDirection(KPanelExtension::Bottom), + m_popupDirection(KPanelApplet::Up), ++ m_iconAlignment(AlignCenter), + m_orientation(Horizontal), + m_size((KIcon::StdSizes)-1), + m_fontPercent(0.40) +@@ -186,6 +188,12 @@ + setArrowDirection(KickerLib::directionToPopupPosition(d)); + } + ++void PanelButton::setIconAlignment(AlignmentFlags align) ++{ ++ m_iconAlignment = align; ++ update(); ++} ++ + void PanelButton::setOrientation(Orientation o) + { + m_orientation = o; +@@ -300,7 +308,9 @@ + + int PanelButton::heightForWidth(int width) const + { +- return preferredDimension(width); ++ int rc=preferredDimension(width); ++ ++ return rc; + } + + const QPixmap& PanelButton::labelIcon() const +@@ -556,11 +566,16 @@ + icon.height() - 2); + } + ++ int y = 0; ++ if (m_iconAlignment & AlignVCenter) ++ y = (height() - icon.height()) / 2; ++ else if (m_iconAlignment & AlignBottom) ++ y = (height() - icon.height()); ++ + if (!m_buttonText.isEmpty() && orientation() == Horizontal) + { + int h = height(); + int w = width(); +- int y = (h - icon.height())/2; + p->save(); + QFont f = font(); + +@@ -629,8 +644,11 @@ + } + else if (!icon.isNull()) + { +- int y = (height() - icon.height()) / 2; +- int x = (width() - icon.width()) / 2; ++ int x = 0; ++ if (m_iconAlignment & AlignHCenter) ++ x = (width() - icon.width()) / 2; ++ else if (m_iconAlignment & AlignRight) ++ x = (width() - icon.width()); + p->drawPixmap(x, y, icon); + } + +@@ -792,7 +810,19 @@ + QString nm = m_iconName; + KIcon::States defaultState = isEnabled() ? KIcon::DefaultState : + KIcon::DisabledState; +- m_icon = ldr->loadIcon(nm, KIcon::Panel, m_size, defaultState, 0L, true); ++ if (nm=="kmenu-suse") ++ { ++ QString pth = locate( "data", "kicker/pics/kmenu_basic.mng" ); ++ if (!pth.isEmpty()) ++ { ++ m_icon = QImage(pth); ++ m_iconh = QPixmap(m_icon); ++ m_iconz = QPixmap(m_icon); ++ return; ++ } ++ } ++ else ++ m_icon = ldr->loadIcon(nm, KIcon::Panel, m_size, defaultState, 0L, true); + + if (m_icon.isNull()) + { +@@ -857,7 +887,7 @@ + connect(this, SIGNAL(pressed()), SLOT(slotExecMenu())); + } + +-void PanelPopupButton::setPopup(QPopupMenu *popup) ++void PanelPopupButton::setPopup(QWidget *popup) + { + if (m_popup) + { +@@ -875,7 +905,7 @@ + } + } + +-QPopupMenu *PanelPopupButton::popup() const ++QWidget *PanelPopupButton::popup() const + { + return m_popup; + } +@@ -954,7 +984,9 @@ + } + + m_popup->adjustSize(); +- m_popup->exec(KickerLib::popupPosition(popupDirection(), m_popup, this)); ++ if(dynamic_cast(m_popup)) ++ static_cast(m_popup)->exec(KickerLib::popupPosition(popupDirection(), m_popup, this)); ++ // else.. hmm. some derived class has to fix it. + } + + void PanelPopupButton::menuAboutToHide() +@@ -964,8 +996,10 @@ + return; + } + +- setDown(false); +- KickerTip::enableTipping(true); ++ if (isDown()) { ++ setDown(false); ++ KickerTip::enableTipping(true); ++ } + } + + void PanelPopupButton::triggerDrag() +@@ -983,3 +1017,5 @@ + m_initialized = initialized; + } + ++ ++ +--- extensions/kasbar/kasbar.cpp (Revision 849788) ++++ extensions/kasbar/kasbar.cpp (Revision 849791) +@@ -719,7 +719,7 @@ + i->setText( "Animated" ); + i->setIcon( KGlobal::iconLoader()->loadIcon( "icons", KIcon::NoGroup, KIcon::SizeMedium ) ); + i->setAnimation( resources()->startupAnimation() ); +- QTimer *aniTimer = new QTimer( i ); ++ QTimer *aniTimer = new QTimer( i, "aniTimer" ); + connect( aniTimer, SIGNAL( timeout() ), i, SLOT( advanceAnimation() ) ); + aniTimer->start( 100 ); + i->setShowAnimation( true ); +--- extensions/kasbar/kasclockitem.cpp (Revision 849788) ++++ extensions/kasbar/kasclockitem.cpp (Revision 849791) +@@ -38,7 +38,7 @@ + { + setCustomPopup( true ); + +- QTimer *t = new QTimer( this ); ++ QTimer *t = new QTimer( this, "t" ); + connect( t, SIGNAL( timeout() ), SLOT( updateTime() ) ); + t->start( 1000 ); + +--- extensions/kasbar/kasstartupitem.cpp (Revision 849788) ++++ extensions/kasbar/kasstartupitem.cpp (Revision 849791) +@@ -79,7 +79,7 @@ + setShowFrame( false ); + setAnimation( resources()->startupAnimation() ); + +- aniTimer = new QTimer( this ); ++ aniTimer = new QTimer( this, "aniTimer" ); + connect( aniTimer, SIGNAL( timeout() ), SLOT( aniTimerFired() ) ); + aniTimer->start( 100 ); + } +--- extensions/kasbar/kasloaditem.cpp (Revision 849788) ++++ extensions/kasbar/kasloaditem.cpp (Revision 849791) +@@ -33,7 +33,7 @@ + KasLoadItem::KasLoadItem( KasBar *parent ) + : KasItem( parent ) + { +- QTimer *t = new QTimer( this ); ++ QTimer *t = new QTimer( this, "KasLoadItem::t" ); + connect( t, SIGNAL( timeout() ), SLOT( updateDisplay() ) ); + t->start( 1000 ); + updateDisplay(); +--- kicker/interfaces/kickoff-search-plugin.h (Revision 0) ++++ kicker/interfaces/kickoff-search-plugin.h (Revision 849791) +@@ -0,0 +1,106 @@ ++/*************************************************************************** ++ * Copyright (C) 2006 by Stephan Binner * ++ * Copyright (c) 2006 Debajyoti Bera * ++ * * ++ * This program is free software; you can redistribute it and/or modify * ++ * it under the terms of the GNU General Public License as published by * ++ * the Free Software Foundation; either version 2 of the License, or * ++ * (at your option) any later version. * ++ * * ++ * This program is distributed in the hope that it will be useful, * ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of * ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * ++ * GNU General Public License for more details. * ++ * * ++ * You should have received a copy of the GNU General Public License * ++ * along with this program; if not, write to the * ++ * Free Software Foundation, Inc., * ++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ++ ***************************************************************************/ ++ ++#ifndef KICKOFF_SEARCH_PLUGIN_H ++#define KICKOFF_SEARCH_PLUGIN_H ++ ++#include "kickoffsearchinterface.h" ++ ++#include ++#include ++#include ++ ++typedef enum { ++ ACTIONS = 0, ++ APPS, ++ BOOKMARKS, ++ NOTES, ++ MAILS, ++ FILES, ++ MUSIC, ++ WEBHIST, ++ CHATS, ++ FEEDS, ++ PICS, ++ VIDEOS, ++ DOCS, ++ OTHER, ++ num_categories ++} CATEGORY; ++ ++class HitMenuItem ++{ ++public: ++ HitMenuItem (int id, int category) ++ : id (id), category (category),score(0) { } /* dummy */ ++ HitMenuItem (QString name, QString info, KURL uri, QString mimetype, int id, int category, QString icon=QString::null, int score = 0) ++ : display_name (name) ++ , display_info (info) ++ , uri (uri) ++ , mimetype (mimetype) ++ , id (id) ++ , category (category) ++ , icon (icon) ++ , score (score) ++ , service (NULL) { } ++ ++ ~HitMenuItem () { } ++ ++ bool operator< (HitMenuItem item) ++ { ++ return ((category == item.category && score > item.score) || (category == item.category && id < item.id) || ++ (category < item.category)); ++ } ++ ++ // FIXME: We dont really need to store display_name and display_info ++ QString display_name; // name to display ++ QString display_info; // other information to display ++ KURL uri; // uri to open when clicked ++ QString mimetype; ++ int id; // id of the item in the menu ++ int category; ++ QString icon; ++ int score; ++ KService::Ptr service; ++ ++ QString quotedPath () const ++ { ++ return uri.path ().replace ('"', "\\\""); ++ } ++}; ++ ++namespace KickoffSearch { ++ ++ class Plugin : public QObject ++ { ++ Q_OBJECT ++ ++ public: ++ Plugin(QObject *parent, const char* name=0); ++ virtual ~Plugin(); ++ ++ virtual bool daemonRunning()=0; ++ virtual void query(QString,bool)=0; ++ ++ KickoffSearchInterface * kickoffSearchInterface(); ++ }; ++}; ++ ++#endif /* KICKOFF_SEARCH_PLUGIN_H */ +--- kicker/interfaces/kickoffsearchinterface.cpp (Revision 0) ++++ kicker/interfaces/kickoffsearchinterface.cpp (Revision 849791) +@@ -0,0 +1,27 @@ ++/*************************************************************************** ++ * Copyright (C) 2006 by Stephan Binner * ++ * * ++ * This program is free software; you can redistribute it and/or modify * ++ * it under the terms of the GNU General Public License as published by * ++ * the Free Software Foundation; either version 2 of the License, or * ++ * (at your option) any later version. * ++ * * ++ * This program is distributed in the hope that it will be useful, * ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of * ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * ++ * GNU General Public License for more details. * ++ * * ++ * You should have received a copy of the GNU General Public License * ++ * along with this program; if not, write to the * ++ * Free Software Foundation, Inc., * ++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ++ ***************************************************************************/ ++ ++#include "kickoffsearchinterface.h" ++ ++KickoffSearch::KickoffSearchInterface::KickoffSearchInterface( QObject* parent, const char* name ) ++ :QObject( parent, name ) ++{ ++} ++ ++#include "kickoffsearchinterface.moc" +--- kicker/interfaces/Makefile.am (Revision 0) ++++ kicker/interfaces/Makefile.am (Revision 849791) +@@ -0,0 +1,12 @@ ++METASOURCES = AUTO ++INCLUDES= -I$(top_srcdir)/src $(all_includes) ++ ++# The library containing the plugin base class ++lib_LTLIBRARIES = libkickoffsearch_interfaces.la ++libkickoffsearch_interfaces_la_SOURCES = kickoff-search-plugin.cpp kickoffsearchinterface.cpp ++libkickoffsearch_interfaces_la_LDFLAGS = $(all_libraries) -version-info 0:0:0 ++ ++kickoffsearchincludedir = $(includedir) ++kickoffsearchinclude_HEADERS = kickoff-search-plugin.h kickoffsearchinterface.h ++ ++kde_servicetypes_DATA = kickoffsearchplugin.desktop +--- kicker/interfaces/kickoffsearchinterface.h (Revision 0) ++++ kicker/interfaces/kickoffsearchinterface.h (Revision 849791) +@@ -0,0 +1,46 @@ ++/*************************************************************************** ++ * Copyright (C) 2006 by Stephan Binner * ++ * * ++ * This program is free software; you can redistribute it and/or modify * ++ * it under the terms of the GNU General Public License as published by * ++ * the Free Software Foundation; either version 2 of the License, or * ++ * (at your option) any later version. * ++ * * ++ * This program is distributed in the hope that it will be useful, * ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of * ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * ++ * GNU General Public License for more details. * ++ * * ++ * You should have received a copy of the GNU General Public License * ++ * along with this program; if not, write to the * ++ * Free Software Foundation, Inc., * ++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ++ ***************************************************************************/ ++ ++#ifndef KICKOFFSEARCHINTERFACE_H ++#define KICKOFFSEARCHINTERFACE_H ++ ++#include ++ ++class HitMenuItem; ++ ++namespace KickoffSearch ++{ ++ class KickoffSearchInterface :public QObject ++ { ++ Q_OBJECT ++ ++ public: ++ KickoffSearchInterface( QObject* parent, const char* name = 0); ++ ++ public: ++ virtual bool anotherHitMenuItemAllowed(int cat) = 0; ++ virtual void addHitMenuItem(HitMenuItem* item) = 0; ++ virtual void searchOver() = 0; ++ virtual void initCategoryTitlesUpdate() = 0; ++ virtual void updateCategoryTitles() = 0; ++ }; ++} ++ ++#endif /* SELECTIONINTERFACE_H */ ++ +--- kicker/interfaces/kickoffsearchplugin.desktop (Revision 0) ++++ kicker/interfaces/kickoffsearchplugin.desktop (Revision 849791) +@@ -0,0 +1,4 @@ ++[Desktop Entry] ++Type=ServiceType ++X-KDE-ServiceType=KickoffSearch/Plugin ++Comment=A search plugin for Kickoff +--- kicker/interfaces/kickoff-search-plugin.cpp (Revision 0) ++++ kicker/interfaces/kickoff-search-plugin.cpp (Revision 849791) +@@ -0,0 +1,37 @@ ++/*************************************************************************** ++ * Copyright (C) 2006 by Stephan Binner * ++ * * ++ * This program is free software; you can redistribute it and/or modify * ++ * it under the terms of the GNU General Public License as published by * ++ * the Free Software Foundation; either version 2 of the License, or * ++ * (at your option) any later version. * ++ * * ++ * This program is distributed in the hope that it will be useful, * ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of * ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * ++ * GNU General Public License for more details. * ++ * * ++ * You should have received a copy of the GNU General Public License * ++ * along with this program; if not, write to the * ++ * Free Software Foundation, Inc., * ++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ++ ***************************************************************************/ ++ ++#include "kickoff-search-plugin.h" ++#include ++ ++KickoffSearch::Plugin::Plugin(QObject *parent, const char* name ) ++ :QObject( parent, name ) ++{ ++} ++ ++KickoffSearch::Plugin::~Plugin() ++{ ++} ++ ++KickoffSearch::KickoffSearchInterface* KickoffSearch::Plugin::kickoffSearchInterface() ++{ ++ return static_cast( parent()->child( 0, "KickoffSearch::KickoffSearchInterface" ) ); ++} ++ ++#include "kickoff-search-plugin.moc" + +Eigenschaftsänderungen: kicker/interfaces +___________________________________________________________________ +Hinzugefügt: svn:ignore + + .deps +libkickoffsearch_interfaces.la +.libs +Makefile +Makefile.in +*.moc + + +--- kicker/core/menumanager.h (Revision 849788) ++++ kicker/core/menumanager.h (Revision 849791) +@@ -28,7 +28,9 @@ + #include + + class PanelKMenu; ++class KMenu; + class KickerClientMenu; ++class KMenuStub; + class PanelPopupButton; + + typedef QValueList KButtonList; +@@ -50,13 +52,12 @@ + bool process(const QCString &fun, const QByteArray &data, QCString& replyType, QByteArray &reply); + + // KMenu controls +- PanelKMenu* kmenu() { return m_kmenu; } +- void showKMenu(); ++ KMenuStub* kmenu() { return m_kmenu; } + void popupKMenu(const QPoint &p); + + void registerKButton(PanelPopupButton *button); + void unregisterKButton(PanelPopupButton *button); +- PanelPopupButton* findKButtonFor(QPopupMenu* menu); ++ PanelPopupButton* findKButtonFor(QWidget* menu); + ~MenuManager(); + + public slots: +@@ -67,7 +68,7 @@ + void applicationRemoved(const QCString&); + + protected: +- PanelKMenu* m_kmenu; ++ KMenuStub* m_kmenu; + typedef QValueList ClientMenuList; + ClientMenuList clientmenus; + +--- kicker/core/kicker.cpp (Revision 849788) ++++ kicker/core/kicker.cpp (Revision 849791) +@@ -48,6 +48,8 @@ + #include "extensionmanager.h" + #include "pluginmanager.h" + #include "menumanager.h" ++#include "k_new_mnu.h" ++#include "k_mnu_stub.h" + #include "k_mnu.h" + #include "showdesktop.h" + #include "panelbutton.h" +@@ -106,6 +108,7 @@ + + KGlobal::iconLoader()->addExtraDesktopThemes(); + ++ KGlobal::locale()->insertCatalogue("kdmgreet"); + KGlobal::locale()->insertCatalogue("libkonq"); + KGlobal::locale()->insertCatalogue("libdmctl"); + KGlobal::locale()->insertCatalogue("libtaskbar"); +@@ -212,7 +215,7 @@ + + void Kicker::showKMenu() + { +- MenuManager::the()->showKMenu(); ++ MenuManager::the()->kmenuAccelActivated(); + } + + void Kicker::popupKMenu(const QPoint &p) +--- kicker/core/container_button.cpp (Revision 849788) ++++ kicker/core/container_button.cpp (Revision 849791) +@@ -43,6 +43,7 @@ + #include "desktopbutton.h" + #include "extensionbutton.h" + #include "kbutton.h" ++#include "knewbutton.h" + #include "kicker.h" + #include "kickerSettings.h" + #include "kickertip.h" +@@ -326,14 +327,20 @@ + : ButtonContainer(opMenu, parent) + { + checkImmutability(config); +- embedButton( new KButton(this) ); ++ if(KickerSettings::legacyKMenu()) ++ embedButton( new KButton(this) ); ++ else ++ embedButton( new KNewButton(this) ); + _actions = PanelAppletOpMenu::KMenuEditor; + } + + KMenuButtonContainer::KMenuButtonContainer(QPopupMenu *opMenu, QWidget* parent) + : ButtonContainer(opMenu, parent) + { +- embedButton( new KButton(this) ); ++ if(KickerSettings::legacyKMenu()) ++ embedButton( new KButton(this) ); ++ else ++ embedButton( new KNewButton(this) ); + _actions = PanelAppletOpMenu::KMenuEditor; + } + +--- kicker/core/main.cpp (Revision 849788) ++++ kicker/core/main.cpp (Revision 849791) +@@ -108,7 +108,7 @@ + appname.sprintf("kicker-screen-%d", kicker_screen_number); + + KAboutData aboutData( appname.data(), I18N_NOOP("KDE Panel"), +- version, description, KAboutData::License_BSD, ++ version, description, KAboutData::License_GPL_V2, + I18N_NOOP("(c) 1999-2004, The KDE Team") ); + + aboutData.addAuthor("Aaron J. Seigo", I18N_NOOP("Current maintainer"), "aseigo@kde.org"); +--- kicker/core/menumanager.cpp (Revision 849788) ++++ kicker/core/menumanager.cpp (Revision 849791) +@@ -31,9 +31,12 @@ + #include "client_mnu.h" + #include "container_extension.h" + #include "global.h" ++#include "k_new_mnu.h" + #include "k_mnu.h" ++#include "k_mnu_stub.h" + #include "kicker.h" + #include "panelbutton.h" ++#include "kickerSettings.h" + + #include "menumanager.h" + #include "menumanager.moc" +@@ -62,7 +65,11 @@ + MenuManager::MenuManager(QObject *parent) + : QObject(parent, "MenuManager"), DCOPObject("MenuManager") + { +- m_kmenu = new PanelKMenu; ++ if (KickerSettings::legacyKMenu()) ++ m_kmenu = new KMenuStub(new PanelKMenu); ++ else ++ m_kmenu = new KMenuStub(new KMenu); ++ + kapp->dcopClient()->setNotifications(true); + connect(kapp->dcopClient(), SIGNAL(applicationRemoved(const QCString&)), + this, SLOT(applicationRemoved(const QCString&))); +@@ -83,14 +90,8 @@ + m_kmenu->selectFirstItem(); + } + +-void MenuManager::showKMenu() +-{ +- m_kmenu->showMenu(); +-} +- + void MenuManager::popupKMenu(const QPoint &p) + { +-// kdDebug(1210) << "popupKMenu()" << endl; + if (m_kmenu->isVisible()) + { + m_kmenu->hide(); +@@ -120,7 +121,7 @@ + m_kbuttons.remove(button); + } + +-PanelPopupButton* MenuManager::findKButtonFor(QPopupMenu* menu) ++PanelPopupButton* MenuManager::findKButtonFor(QWidget* menu) + { + KButtonList::const_iterator itEnd = m_kbuttons.constEnd(); + for (KButtonList::const_iterator it = m_kbuttons.constBegin(); it != itEnd; ++it) +@@ -169,7 +170,7 @@ + const QSize size = m_kmenu->sizeHint(); + m_kmenu->resize(size.width(),size.height()); + +- PanelPopupButton* button = findKButtonFor(m_kmenu); ++ PanelPopupButton* button = findKButtonFor(m_kmenu->widget()); + + // let's unhide the panel while we're at it. traverse the widget + // hierarchy until we find the panel, if any +@@ -189,7 +190,6 @@ + + menuParent = menuParent->parent(); + } +- + button->showMenu(); + } + } +@@ -213,7 +213,7 @@ + + void MenuManager::removeMenu(QCString menu) + { +- bool iterate = true; ++ bool iterate = true, need_adjustSize = false; + ClientMenuList::iterator it = clientmenus.begin(); + for (; it != clientmenus.end(); iterate ? ++it : it) + { +@@ -224,15 +224,17 @@ + m_kmenu->removeClientMenu(m->idInParentMenu); + it = clientmenus.erase(it); + iterate = false; ++ need_adjustSize = true; + } + } +- m_kmenu->adjustSize(); ++ if (need_adjustSize) ++ m_kmenu->adjustSize(); + } + + + void MenuManager::applicationRemoved(const QCString& appRemoved) + { +- bool iterate = true; ++ bool iterate = true, need_adjustSize = false; + ClientMenuList::iterator it = clientmenus.begin(); + for (; it != clientmenus.end(); iterate ? ++it : it) + { +@@ -243,9 +245,11 @@ + m_kmenu->removeClientMenu(m->idInParentMenu); + it = clientmenus.erase(it); + iterate = false; ++ need_adjustSize = true; + } + } +- m_kmenu->adjustSize(); ++ if (need_adjustSize) ++ m_kmenu->adjustSize(); + } + + bool MenuManager::process(const QCString &fun, const QByteArray &data, +--- kicker/core/unhidetrigger.cpp (Revision 849788) ++++ kicker/core/unhidetrigger.cpp (Revision 849791) +@@ -39,7 +39,7 @@ + , _lastXineramaScreen( -1 ) + , enabledCount( 0 ) + { +- _timer = new QTimer( this ); ++ _timer = new QTimer( this, "UnhideTrigger" ); + connect( _timer, SIGNAL(timeout()), SLOT(pollMouse()) ); + } + +--- kicker/core/applethandle.cpp (Revision 849788) ++++ kicker/core/applethandle.cpp (Revision 849791) +@@ -150,7 +150,7 @@ + { + if (!m_handleHoverTimer) + { +- m_handleHoverTimer = new QTimer(this); ++ m_handleHoverTimer = new QTimer(this, "m_handleHoverTimer"); + connect(m_handleHoverTimer, SIGNAL(timeout()), + this, SLOT(checkHandleHover())); + m_applet->installEventFilter(this); +@@ -177,11 +177,7 @@ + m_drawHandle = true; + resetLayout(); + +- if (m_handleHoverTimer) +- { +- m_handleHoverTimer->start(250); +- } +- break; ++ break; + } + + case QEvent::Leave: +@@ -191,6 +187,11 @@ + break; + } + ++ if (m_handleHoverTimer) ++ { ++ m_handleHoverTimer->start(250); ++ } ++ + QWidget* w = dynamic_cast(o); + + bool nowDrawIt = false; +@@ -207,11 +208,6 @@ + + if (nowDrawIt != m_drawHandle) + { +- if (m_handleHoverTimer) +- { +- m_handleHoverTimer->stop(); +- } +- + m_drawHandle = nowDrawIt; + resetLayout(); + } +@@ -297,6 +293,11 @@ + } + + m_menuButton->setDown(false); ++ ++ if (m_handleHoverTimer) ++ { ++ m_handleHoverTimer->start(250); ++ } + } + + AppletHandleDrag::AppletHandleDrag(AppletHandle* parent) +--- kicker/core/containerarea.cpp 2009/11/20 21:00:18 1.1 ++++ kicker/core/containerarea.cpp 2009/11/20 21:00:38 +@@ -87,7 +87,8 @@ + m_immutable(_c->isImmutable()), + m_updateBackgroundsCalled(false), + m_layout(0), +- m_addAppletDialog(0) ++ m_addAppletDialog(0), ++ _autoScrollTimer(0, "ContainerArea::autoScrollTimer") + { + setBackgroundOrigin( WidgetOrigin ); + +--- kicker/core/Makefile.am (Revision 849788) ++++ kicker/core/Makefile.am (Revision 849791) +@@ -1,6 +1,6 @@ + INCLUDES = -I$(srcdir)/../../libkicker -I../../libkicker \ +- -I$(srcdir)/../ui -I$(srcdir)/../buttons -I$(top_srcdir)/libkonq \ +- $(all_includes) ++ -I../ui -I$(srcdir)/../ui -I$(srcdir)/../buttons -I$(top_srcdir)/libkonq \ ++ $(all_includes) + + noinst_LTLIBRARIES = libkicker_core.la + +--- kicker/Makefile.am (Revision 849788) ++++ kicker/Makefile.am (Revision 849791) +@@ -1,6 +1,6 @@ + INCLUDES = $(all_includes) + +-SUBDIRS = core ui buttons . ++SUBDIRS = core ui buttons interfaces . + + bin_PROGRAMS = + lib_LTLIBRARIES = +@@ -9,7 +9,7 @@ + CLEANFILES = dummy.cpp + + kicker_la_LIBADD = core/libkicker_core.la buttons/libkicker_buttons.la \ +- ui/libkicker_ui.la ../libkicker/libkickermain.la $(LIB_KIO) $(LIB_KUTILS) ++ ui/libkicker_ui.la ../libkicker/libkickermain.la $(LIB_KIO) $(LIB_KUTILS) $(LIB_KABC) + + kicker_la_SOURCES = dummy.cpp + kicker_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries) +--- kicker/ui/browser_mnu.cpp (Revision 849788) ++++ kicker/ui/browser_mnu.cpp (Revision 849791) +@@ -329,7 +329,7 @@ + if(_mimemap.count() > 0) { + + if(!_mimecheckTimer) +- _mimecheckTimer = new QTimer(this); ++ _mimecheckTimer = new QTimer(this, "_mimecheckTimer"); + + connect(_mimecheckTimer, SIGNAL(timeout()), SLOT(slotMimeCheck())); + _mimecheckTimer->start(0); +--- kicker/ui/flipscrollview.cpp (Revision 0) ++++ kicker/ui/flipscrollview.cpp (Revision 849791) +@@ -0,0 +1,324 @@ ++/***************************************************************** ++ ++Copyright (c) 2006 Will Stephenson ++ ++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 ++#include ++#include ++#include ++ ++#include "itemview.h" ++#include "flipscrollview.h" ++#include "kickerSettings.h" ++ ++/* Flip scroll steps, as percentage of itemview width to scroll per ++ * step. Assumes the itemview is scrolled in ten steps */ ++ ++/* slow start, then fast */ ++//static const double scrollSteps[] = { 0.05, 0.05, 0.1125, 0.1125, 0.1125, 0.1125, 0.1125, 0.1125, 0.1125, 0.1125 }; ++ ++/* slow fast slow */ ++//static const double scrollSteps[] = { 0.05, 0.05, 0.13, 0.13, 0.15, 0.13, 0.13, 0.13, 0.05, 0.05 }; ++ ++/* slow veryfast slow */ ++static const double scrollSteps[] = { 0.03, 0.03, 0.147, 0.147, 0.147, 0.147, 0.147, 0.147, 0.03, 0.028 }; ++; ++ ++BackFrame::BackFrame( QWidget *parent ) ++ : QFrame( parent ), mouse_inside( false ) ++{ ++ setFrameStyle( QFrame::NoFrame ); ++ if ( QApplication::reverseLayout() ) ++ left_triangle.load( locate( "data", "kicker/pics/right_triangle.png" ) ); ++ else ++ left_triangle.load( locate( "data", "kicker/pics/left_triangle.png" ) ); ++} ++ ++void BackFrame::drawContents( QPainter *p ) ++{ ++ QColor gray( 230, 230, 230 ); ++ if ( mouse_inside ) ++ p->fillRect( 3, 3, width() - 6, height() - 6, colorGroup().color( QColorGroup::Highlight ) ); ++ else ++ p->fillRect( 3, 3, width() - 6, height() - 6, gray ); ++ p->setPen( gray.dark(110) ); ++ p->drawRect( 3, 3, width() - 6, height() - 6 ); ++ ++ int pixsize = ( width() - 6 ) * 3 / 5; ++ QImage i = left_triangle.convertToImage().smoothScale( pixsize, pixsize ); ++ QPixmap tri; ++ tri.convertFromImage( i ); ++ ++ p->drawPixmap( ( width() - tri.width() ) / 2, ( height() - tri.height() ) / 2, tri ); ++} ++ ++void BackFrame::enterEvent( QEvent *e ) ++{ ++ mouse_inside = true; ++ update(); ++} ++ ++void BackFrame::leaveEvent( QEvent *e ) ++{ ++ mouse_inside = false; ++ update(); ++} ++ ++void BackFrame::mousePressEvent ( QMouseEvent * e ) ++{ ++ emit clicked(); ++} ++ ++FlipScrollView::FlipScrollView( QWidget * parent, const char * name ) ++ : QScrollView( parent, name ), mState( StoppedLeft ), mScrollDirection( 1 ), mShowBack( false ) ++{ ++ setVScrollBarMode( QScrollView::AlwaysOff ); ++ setHScrollBarMode( QScrollView::AlwaysOff ); ++ setFrameStyle( QFrame::NoFrame ); ++ mLeftView = new ItemView( this, "left_view" ); ++ addChild( mLeftView ); ++ ++ mRightView = new ItemView( this, "right_view" ); ++ addChild( mRightView ); ++ ++ mTimer = new QTimer( this, "mTimer" ); ++ connect( mTimer, SIGNAL( timeout() ), SLOT( slotScrollTimer() ) ); ++ ++ connect( mLeftView, SIGNAL( startService(KService::Ptr) ), ++ SIGNAL( startService(KService::Ptr) ) ); ++ connect( mLeftView, SIGNAL( startURL(const QString& ) ), ++ SIGNAL( startURL(const QString& ) ) ); ++ connect( mLeftView, SIGNAL( rightButtonPressed(QListViewItem*,const QPoint&,int) ), ++ SIGNAL( rightButtonPressed(QListViewItem*,const QPoint&,int) ) ); ++ connect( mRightView, SIGNAL( startService(KService::Ptr) ), ++ SIGNAL( startService(KService::Ptr) ) ); ++ connect( mRightView, SIGNAL( startURL(const QString& ) ), ++ SIGNAL( startURL(const QString& ) ) ); ++ connect( mRightView, SIGNAL( rightButtonPressed(QListViewItem*,const QPoint&,int) ), ++ SIGNAL( rightButtonPressed(QListViewItem*,const QPoint&,int) ) ); ++ ++ // wild hack to make sure it has correct width ++ mLeftView->setVScrollBarMode( QScrollView::AlwaysOn ); ++ mRightView->setVScrollBarMode( QScrollView::AlwaysOn ); ++ mLeftView->setVScrollBarMode( QScrollView::Auto ); ++ mRightView->setVScrollBarMode( QScrollView::Auto ); ++ ++ mBackrow = new BackFrame( this ); ++ mBackrow->resize( 24, 100 ); ++ connect( mBackrow, SIGNAL( clicked() ), SIGNAL( backButtonClicked() ) ); ++} ++ ++ItemView* FlipScrollView::prepareRightMove() ++{ ++ if ( mState != StoppedLeft ) ++ { ++ mTimer->stop(); ++ ItemView *swap = mLeftView; ++ mLeftView = mRightView; ++ mRightView = swap; ++ moveChild( mLeftView, 0, 0 ); ++ moveChild( mRightView, width(), 0 ); ++ mBackrow->hide(); ++ mRightView->resize( width(), height() ); ++ mLeftView->resize( width(), height() ); ++ setContentsPos( 0, 0 ); ++ } ++ ++ mState = StoppedLeft; ++ mRightView->clear(); ++ return mRightView; ++} ++ ++void FlipScrollView::showBackButton( bool enable ) ++{ ++ kdDebug() << "FlipScrollView::showBackButton " << enable << endl; ++ mShowBack = enable; ++} ++ ++ItemView* FlipScrollView::prepareLeftMove(bool clear) ++{ ++ if ( mState != StoppedRight ) ++ { ++ mTimer->stop(); ++ ItemView *swap = mLeftView; ++ mLeftView = mRightView; ++ mRightView = swap; ++ moveChild( mLeftView, 0, 0 ); ++ moveChild( mRightView, width(), 0 ); ++ mRightView->resize( width(), height() ); ++ mLeftView->resize( width(), height() ); ++ mBackrow->hide(); ++ setContentsPos( width(), 0 ); ++ } ++ ++ mState = StoppedRight; ++ if (clear) ++ mLeftView->clear(); ++ return mLeftView; ++} ++ ++void FlipScrollView::viewportResizeEvent ( QResizeEvent * ) ++{ ++ mLeftView->resize( size() ); ++ mRightView->resize( width() - mBackrow->width(), height() ); ++ mBackrow->resize( mBackrow->width(), height() ); ++ resizeContents( width() * 2, height() ); ++ moveChild( mBackrow, width(), 0 ); ++ moveChild( mRightView, width() + mBackrow->width(), 0 ); ++ setContentsPos( 0, 0 ); ++} ++ ++ItemView *FlipScrollView::currentView() const ++{ ++ if ( mState == StoppedRight ) ++ return mRightView; ++ else ++ return mLeftView; ++} ++ ++ItemView *FlipScrollView::leftView() const ++{ ++ return mLeftView; ++} ++ ++ItemView *FlipScrollView::rightView() const ++{ ++ return mRightView; ++} ++ ++FlipScrollView::~FlipScrollView() {} ++ ++static const int max_steps = 10; ++ ++void FlipScrollView::slotScrollTimer() ++{ ++ mStepsRemaining--; ++ assert( mStepsRemaining >= 0 && mStepsRemaining < int(sizeof( scrollSteps ) / sizeof( double )) ); ++ if (KickerSettings::scrollFlipView()) ++ scrollBy( ( int )( mScrollDirection * mLeftView->width() * scrollSteps[ mStepsRemaining ] ), 0 ); ++ else ++ scrollBy( ( int )( mScrollDirection * mLeftView->width()), 0 ); ++ ++ if ( mStepsRemaining == 0 ) ++ { ++ if ( mState == ScrollingRight ) ++ { ++ mState = StoppedRight; ++ setContentsPos( width(), 0 ); ++ } else { ++ mState = StoppedLeft; ++ setContentsPos( 0, 0 ); ++ } ++ ++ kdDebug() << "slotScrollTimer " << mShowBack << endl; ++ ++ if ( mShowBack ) ++ { ++ mBackrow->show(); ++ if ( mState == StoppedRight ) ++ { ++ ++ if ( QApplication::reverseLayout() ) ++ moveChild( mRightView, width(), 0 ); ++ else ++ moveChild( mRightView, width() + mBackrow->width(), 0 ); ++ mRightView->resize( width() - mBackrow->width(), height() ); ++ mLeftView->resize( width(), height() ); ++ if ( QApplication::reverseLayout() ) ++ moveChild( mBackrow, width() + mRightView->width(), 0 ); ++ else ++ moveChild( mBackrow, width(), 0 ); ++ moveChild( mLeftView, 0, 0 ); ++ } else ++ { ++ moveChild( mRightView, width(), 0 ); ++ mRightView->resize( width(), height() ); ++ mLeftView->resize( width() - mBackrow->width(), height() ); ++ if ( QApplication::reverseLayout() ) ++ { ++ moveChild( mBackrow, mLeftView->width(), 0 ); ++ moveChild( mLeftView, 0, 0 ); ++ } ++ else ++ { ++ moveChild( mBackrow, 0, 0 ); ++ moveChild( mLeftView, mBackrow->width(), 0 ); ++ } ++ } ++ } else ++ mBackrow->hide(); ++ ++ if (!mSelectMenuPath.isEmpty()) { ++ if (mSelectMenuPath=="kicker:/goup/") { ++ currentView()->setSelected(currentView()->firstChild(),true); ++ currentView()->firstChild()->repaint(); ++ } ++ else { ++ QListViewItem * child = currentView()->firstChild(); ++ while( child ) { ++ KMenuItem* kitem = dynamic_cast(child); ++ if (kitem && kitem->menuPath()==mSelectMenuPath) { ++ currentView()->setSelected(child,true); ++ kdDebug() << "child repaint\n"; ++ child->repaint(); ++ break; ++ } ++ child = child->nextSibling(); ++ } ++ } ++ } ++ mLeftView->setVScrollBarMode( QScrollView::Auto ); ++ mRightView->setVScrollBarMode( QScrollView::Auto ); ++ mTimer->stop(); ++ mLeftView->setMouseMoveSelects( true ); ++ mRightView->setMouseMoveSelects( true ); ++ } ++} ++ ++void FlipScrollView::flipScroll(const QString& selectMenuPath) ++{ ++ if ( mState == StoppedLeft ) ++ { ++ mState = ScrollingRight; ++ mScrollDirection = 1; ++ } ++ else ++ { ++ mState = ScrollingLeft; ++ mScrollDirection = -1; ++ } ++ ++ mLeftView->setVScrollBarMode( QScrollView::AlwaysOff ); ++ mRightView->setVScrollBarMode( QScrollView::AlwaysOff ); ++ if (KickerSettings::scrollFlipView()) ++ mStepsRemaining = max_steps; ++ else ++ mStepsRemaining = 1; ++ mTimer->start( 30 ); ++ mSelectMenuPath = selectMenuPath; ++ if (!mSelectMenuPath.isEmpty()) { ++ mLeftView->setMouseMoveSelects( false ); ++ mRightView->setMouseMoveSelects( false ); ++ } ++} ++ ++#include "flipscrollview.moc" +--- kicker/ui/query.cpp (Revision 0) ++++ kicker/ui/query.cpp (Revision 849791) +@@ -0,0 +1,136 @@ ++/***************************************************************** ++ ++ Copyright (c) 2006 Stephan Binner ++ ++ 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 "query.h" ++#include ++ ++Query::Query() ++{ ++ alternatives.setAutoDelete(true); ++} ++ ++void Query::clear() ++{ ++ query_term = QString::null; ++ alternatives.clear(); ++} ++ ++void Query::set(const QString &term) ++{ ++ query_term = term; ++ alternatives.clear(); ++ ++ current_alternative = new Alternative; ++ current_part = QString::null; ++ within_quotes = false; ++ exclude_part = false; ++ ++ for (uint index=0;indexexcludes+=current_part.lower(); ++ else ++ current_alternative->includes+=current_part.lower(); ++ } ++ within_quotes = false; ++ exclude_part = false; ++ current_part = QString::null; ++} ++ ++QString Query::get() const ++{ ++ return query_term; ++} ++ ++bool Query::matches(const QString &term) ++{ ++ QString lower_term = term.lower(); ++ ++ for (Alternative* alt=alternatives.first(); alt; alt=alternatives.next()) { ++ if (!alt->includes.count()) ++ continue; ++ ++ bool next_alternative = false; ++ ++ for ( QStringList::ConstIterator it = alt->excludes.begin(); it != alt->excludes.end(); ++it ) { ++ if ( lower_term.find(*it)!=-1 ) { ++ next_alternative = true; ++ continue; ++ } ++ } ++ if (next_alternative) ++ continue; ++ ++ for ( QStringList::ConstIterator it = alt->includes.begin(); it != alt->includes.end(); ++it ) { ++ if ( lower_term.find(*it)==-1 ) { ++ next_alternative = true; ++ continue; ++ } ++ } ++ if (next_alternative) ++ continue; ++ ++//kdDebug() << "Found hit in '" << term << "'" << endl; ++ return true; ++ } ++ ++ return false; ++} +--- kicker/ui/k_new_mnu.cpp (Revision 0) ++++ kicker/ui/k_new_mnu.cpp (Revision 849791) +@@ -0,0 +1,3779 @@ ++/***************************************************************** ++ ++ Copyright (c) 1996-2000 the kicker authors. See file AUTHORS. ++ Copyright (c) 2006 Debajyoti Bera ++ Copyright (c) 2006 Dirk Mueller ++ ++ 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 ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "client_mnu.h" ++#include "container_base.h" ++#include "global.h" ++#include "knewbutton.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 "flipscrollview.h" ++#include "itemview.h" ++#include ++#include ++#include ++ ++#include "media_watcher.h" ++#include "k_mnu.h" ++#include "k_new_mnu.h" ++#include "k_new_mnu.moc" ++#include "kickoff_bar.h" ++ ++#define WAIT_BEFORE_QUERYING 700 ++ ++#define IDS_PER_CATEGORY 20 ++#define ACTIONS_ID_BASE 10 ++#define APP_ID_BASE 10 + IDS_PER_CATEGORY ++#define BOOKMARKS_ID_BASE 10 + (IDS_PER_CATEGORY * 2) ++#define NOTES_ID_BASE 10 + (IDS_PER_CATEGORY * 3) ++#define MAIL_ID_BASE 10 + (IDS_PER_CATEGORY * 4) ++#define FILE_ID_BASE 10 + (IDS_PER_CATEGORY * 5) ++#define MUSIC_ID_BASE 10 + (IDS_PER_CATEGORY * 6) ++#define WEBHIST_ID_BASE 10 + (IDS_PER_CATEGORY * 7) ++#define CHAT_ID_BASE 10 + (IDS_PER_CATEGORY * 8) ++#define FEED_ID_BASE 10 + (IDS_PER_CATEGORY * 9) ++#define PIC_ID_BASE 10 + (IDS_PER_CATEGORY * 10) ++#define VIDEO_ID_BASE 10 + (IDS_PER_CATEGORY * 11) ++#define DOC_ID_BASE 10 + (IDS_PER_CATEGORY * 12) ++#define OTHER_ID_BASE 10 + (IDS_PER_CATEGORY * 13) ++ ++static QString calculate(const QString &exp) ++{ ++ QString result, cmd; ++ const QString bc = KStandardDirs::findExe("bc"); ++ if ( !bc.isEmpty() ) ++ cmd = QString("echo %1 | %2").arg(KProcess::quote(exp), KProcess::quote(bc)); ++ else ++ cmd = QString("echo $((%1))").arg(exp); ++ FILE *fs = popen(QFile::encodeName(cmd).data(), "r"); ++ if (fs) ++ { ++ QTextStream ts(fs, IO_ReadOnly); ++ result = ts.read().stripWhiteSpace(); ++ pclose(fs); ++ } ++ return result; ++} ++ ++static QString workaroundStringFreeze(const QString& str) ++{ ++ QString s = str; ++ ++ s.replace("","&"); ++ QRegExp re("<[^>]+>"); ++ re.setMinimal(true); ++ re.setCaseSensitive(false); ++ ++ s.replace(re, ""); ++ s = s.simplifyWhiteSpace(); ++ ++ return s; ++} ++ ++int base_category_id[] = {ACTIONS_ID_BASE, APP_ID_BASE, BOOKMARKS_ID_BASE, NOTES_ID_BASE, MAIL_ID_BASE, ++ FILE_ID_BASE, MUSIC_ID_BASE, WEBHIST_ID_BASE, CHAT_ID_BASE, FEED_ID_BASE, ++ PIC_ID_BASE, VIDEO_ID_BASE, DOC_ID_BASE, OTHER_ID_BASE}; ++ ++#include ++ ++static int used_size( QLabel *label, int oldsize ) ++{ ++ QSimpleRichText st( label->text(), KGlobalSettings::toolBarFont() ); ++ st.setWidth( oldsize ); ++ return QMAX( st.widthUsed(), oldsize ); ++} ++ ++KMenu::KMenu() ++ : KMenuBase(0, "SUSE::Kickoff::KMenu") ++ , m_sloppyTimer(0, "KNewMenu::sloppyTimer"), m_mediaFreeTimer(0, "KNewMenu::mediaFreeTimer"), ++ m_iconName(QString::null), m_orientation(UnDetermined), m_search_plugin( 0 ) ++{ ++ setMouseTracking(true); ++ connect(&m_sloppyTimer, SIGNAL(timeout()), SLOT(slotSloppyTimeout())); ++ ++ // set the first client id to some arbitrarily large value. ++ client_id = 10000; ++ // Don't automatically clear the main menu. ++ actionCollection = new KActionCollection(this); ++ ++ connect(Kicker::the(), SIGNAL(configurationChanged()), ++ this, SLOT(configChanged())); ++ ++ KUser * user = new KUser(); ++ ++ char hostname[256]; ++ hostname[0] = '\0'; ++ if (!gethostname( hostname, sizeof(hostname) )) ++ hostname[sizeof(hostname)-1] = '\0'; ++ ++ m_userInfo->setText( i18n( "User %1 on %2" ) ++ .arg( user->loginName() ).arg( hostname ) ); ++ setupUi(); ++ ++ m_userInfo->setBackgroundMode( PaletteBase ); ++ QColor userInfoColor = QApplication::palette().color( QPalette::Normal, QColorGroup::Mid ); ++ if ( qGray( userInfoColor.rgb() ) > 120 ) ++ userInfoColor = userInfoColor.dark( 200 ); ++ else ++ userInfoColor = userInfoColor.light( 200 ); ++ m_userInfo->setPaletteForegroundColor( userInfoColor ); ++ ++ m_tabBar = new KickoffTabBar(this, "m_tabBar"); ++ connect(m_tabBar, SIGNAL(tabClicked(QTab*)), SLOT(tabClicked(QTab*))); ++ ++ const int tab_icon_size = 32; ++ ++ m_tabs[FavoriteTab] = new QTab; ++ m_tabBar->addTab(m_tabs[FavoriteTab]); ++ m_tabBar->setToolTip(FavoriteTab, "" + i18n( "Most commonly used applications and documents" ) + "" ); ++ m_tabs[ApplicationsTab] = new QTab; ++ m_tabBar->addTab(m_tabs[ApplicationsTab]); ++ m_tabBar->setToolTip(ApplicationsTab, "" + i18n( "List of installed applications" ) + ++ "" ); ++ ++ m_tabs[ComputerTab] = new QTab; ++ m_tabBar->addTab(m_tabs[ComputerTab]); ++ m_tabBar->setToolTip(ComputerTab, "" + i18n( "Information and configuration of your " ++ "system, access to personal files, network resources and connected disk drives") ++ + ""); ++#if 0 ++ m_tabs[SearchTab] = new QTab; ++ m_tabBar->addTab(m_tabs[SearchTab]); ++#endif ++ m_tabs[HistoryTab] = new QTab; ++ m_tabBar->addTab(m_tabs[HistoryTab]); ++ m_tabBar->setToolTip(HistoryTab, "" + i18n( "Recently used applications and documents" ) + ++ "" ); ++ m_tabs[LeaveTab] = new QTab; ++ m_tabBar->addTab(m_tabs[LeaveTab]); ++ m_tabBar->setToolTip(LeaveTab, i18n("Logout, switch user, switch off or reset," ++ " suspend of the system" ) + "" ); ++ ++ if (KickerSettings::kickoffTabBarFormat() != KickerSettings::IconOnly) { ++ m_tabs[FavoriteTab]->setText(workaroundStringFreeze(i18n("

Favorites

"))); ++ m_tabs[HistoryTab]->setText(workaroundStringFreeze(i18n("

History

"))); ++ m_tabs[ComputerTab]->setText( ++ workaroundStringFreeze(i18n("

Computer

"))); ++ m_tabs[ApplicationsTab]->setText(workaroundStringFreeze(i18n("

Applications

"))); ++ m_tabs[LeaveTab]->setText( ++ workaroundStringFreeze(i18n("

Leave

"))); ++ } ++ ++ if (KickerSettings::kickoffTabBarFormat() != KickerSettings::LabelOnly) { ++ m_tabs[FavoriteTab]->setIconSet(BarIcon("bookmark", tab_icon_size)); ++ m_tabs[HistoryTab]->setIconSet(BarIcon("recently_used", tab_icon_size)); ++ m_tabs[ComputerTab]->setIconSet(BarIcon("system", tab_icon_size)); ++ m_tabs[ApplicationsTab]->setIconSet(BarIcon("player_playlist", tab_icon_size)); ++ m_tabs[LeaveTab]->setIconSet(BarIcon("leave", tab_icon_size)); ++ } ++ ++ connect(m_tabBar, SIGNAL(selected(int)), m_stacker, SLOT(raiseWidget(int))); ++ connect(m_stacker, SIGNAL(aboutToShow(int)), m_tabBar, SLOT(setCurrentTab(int))); ++ ++ m_favoriteView = new FavoritesItemView (m_stacker, "m_favoriteView"); ++ m_favoriteView->setAcceptDrops(true); ++ m_favoriteView->setItemsMovable(true); ++ m_stacker->addWidget(m_favoriteView, FavoriteTab); ++ ++ m_recentlyView = new ItemView (m_stacker, "m_recentlyView"); ++ m_stacker->addWidget(m_recentlyView, HistoryTab); ++ ++ m_systemView = new ItemView(m_stacker, "m_systemView"); ++ m_stacker->addWidget(m_systemView, ComputerTab ); ++ ++ m_browserView = new FlipScrollView(m_stacker, "m_browserView"); ++ m_stacker->addWidget(m_browserView, ApplicationsTab); ++ connect( m_browserView, SIGNAL( backButtonClicked() ), SLOT( slotGoBack() ) ); ++ ++ m_exitView = new FlipScrollView(m_stacker, "m_exitView"); ++ m_stacker->addWidget(m_exitView, LeaveTab); ++ connect( m_exitView, SIGNAL( backButtonClicked() ), SLOT( slotGoExitMainMenu() ) ); ++ ++ m_searchWidget = new QVBox (m_stacker, "m_searchWidget"); ++ m_searchWidget->setSpacing(0); ++ m_stacker->addWidget(m_searchWidget, 5); ++ ++ // search provider icon ++ QPixmap icon; ++ KURIFilterData data; ++ QStringList list; ++ data.setData( QString("some keyword") ); ++ list << "kurisearchfilter" << "kuriikwsfilter"; ++ ++ if ( KURIFilter::self()->filterURI(data, list) ) { ++ QString iconPath = locate("cache", KMimeType::favIconForURL(data.uri()) + ".png"); ++ if ( iconPath.isEmpty() ) ++ icon = SmallIcon("enhanced_browsing"); ++ else ++ icon = QPixmap( iconPath ); ++ } ++ else ++ icon = SmallIcon("enhanced_browsing"); ++ ++ m_searchResultsWidget = new ItemView (m_searchWidget, "m_searchResultsWidget"); ++ m_searchResultsWidget->setItemMargin(4); ++ m_searchResultsWidget->setIconSize(16); ++ m_searchActions = new ItemView (m_searchWidget, "m_searchActions"); ++ m_searchActions->setFocusPolicy(QWidget::NoFocus); ++ m_searchActions->setItemMargin(4); ++ m_searchInternet = new QListViewItem(m_searchActions, i18n("Search Internet")); ++ m_searchInternet->setPixmap(0,icon); ++ setTabOrder(m_kcommand, m_searchResultsWidget); ++ ++ m_kerryInstalled = !KStandardDirs::findExe(QString::fromLatin1("kerry")).isEmpty(); ++ m_isShowing = false; ++ ++ if (!m_kerryInstalled) { ++ m_searchIndex = 0; ++ m_searchActions->setMaximumHeight(5+m_searchInternet->height()); ++ } ++ else { ++ m_searchIndex = new QListViewItem(m_searchActions, i18n("Search Index")); ++ m_searchIndex->setPixmap(0,SmallIcon("kerry")); ++ m_searchActions->setMaximumHeight(5+m_searchIndex->height()*2); ++ } ++ connect(m_searchActions, SIGNAL(clicked(QListViewItem*)), SLOT(searchActionClicked(QListViewItem*))); ++ connect(m_searchActions, SIGNAL(returnPressed(QListViewItem*)), SLOT(searchActionClicked(QListViewItem*))); ++ connect(m_searchActions, SIGNAL(spacePressed(QListViewItem*)), SLOT(searchActionClicked(QListViewItem*))); ++ ++ connect(m_searchResultsWidget, SIGNAL(startService(KService::Ptr)), SLOT(slotStartService(KService::Ptr))); ++ connect(m_searchResultsWidget, SIGNAL(startURL(const QString&)), SLOT(slotStartURL(const QString&))); ++ connect(m_searchResultsWidget, SIGNAL(rightButtonPressed( QListViewItem*, const QPoint &, int )), SLOT(slotContextMenuRequested( QListViewItem*, const QPoint &, int ))); ++ ++ connect(m_recentlyView, SIGNAL(startService(KService::Ptr)), SLOT(slotStartService(KService::Ptr))); ++ connect(m_recentlyView, SIGNAL(startURL(const QString&)), SLOT(slotStartURL(const QString&))); ++ connect(m_recentlyView, SIGNAL(rightButtonPressed( QListViewItem*, const QPoint &, int )), SLOT(slotContextMenuRequested( QListViewItem*, const QPoint &, int ))); ++ ++ connect(m_favoriteView, SIGNAL(startService(KService::Ptr)), SLOT(slotStartService(KService::Ptr))); ++ connect(m_favoriteView, SIGNAL(startURL(const QString&)), SLOT(slotStartURL(const QString&))); ++ connect(m_favoriteView, SIGNAL(rightButtonPressed( QListViewItem*, const QPoint &, int )), SLOT(slotContextMenuRequested( QListViewItem*, const QPoint &, int ))); ++ connect(m_favoriteView, SIGNAL(moved(QListViewItem*, QListViewItem*, QListViewItem*)), SLOT(slotFavoritesMoved( QListViewItem*, QListViewItem*, QListViewItem* ))); ++ ++ connect(m_systemView, SIGNAL(startURL(const QString&)), SLOT(slotStartURL(const QString&))); ++ connect(m_systemView, SIGNAL(startService(KService::Ptr)), SLOT(slotStartService(KService::Ptr))); ++ connect(m_systemView, SIGNAL(rightButtonPressed( QListViewItem*, const QPoint &, int )), SLOT(slotContextMenuRequested( QListViewItem*, const QPoint &, int ))); ++ ++ connect(m_browserView, SIGNAL(startURL(const QString&)), SLOT(slotGoSubMenu(const QString&))); ++ connect(m_browserView, SIGNAL(startService(KService::Ptr)), SLOT(slotStartService(KService::Ptr))); ++ connect(m_browserView, SIGNAL(rightButtonPressed( QListViewItem*, const QPoint &, int )), SLOT(slotContextMenuRequested( QListViewItem*, const QPoint &, int ))); ++ ++ connect(m_exitView, SIGNAL(startURL(const QString&)), SLOT(slotStartURL(const QString&))); ++ connect(m_exitView, SIGNAL(rightButtonPressed( QListViewItem*, const QPoint &, int )), SLOT(slotContextMenuRequested( QListViewItem*, const QPoint &, int ))); ++ ++ m_kcommand->setDuplicatesEnabled( false ); ++ m_kcommand->setLineEdit(new KLineEdit(m_kcommand, "m_kcommand-lineedit")); ++ m_kcommand->setCompletionMode( KGlobalSettings::CompletionAuto ); ++ connect(m_kcommand, SIGNAL(cleared()), SLOT(clearedHistory())); ++ connect(m_kcommand->lineEdit(), SIGNAL(returnPressed()), SLOT(searchAccept())); ++ connect(m_kcommand->lineEdit(), SIGNAL(textChanged(const QString &)), SLOT(searchChanged(const QString &))); ++ ++ // URI Filter meta object... ++ m_filterData = new KURIFilterData(); ++ ++ max_category_id = new int [num_categories]; ++ categorised_hit_total = new int [num_categories]; ++ ++ input_timer = new QTimer (this, "input_timer"); ++ connect( input_timer, SIGNAL(timeout()), this, SLOT(doQuery()) ); ++ ++ init_search_timer = new QTimer (this, "init_search_timer"); ++ connect( init_search_timer, SIGNAL(timeout()), this, SLOT(initSearch()) ); ++ init_search_timer->start(2000, true); ++ ++ connect( m_favoriteView, SIGNAL( dropped (QDropEvent *, QListViewItem * ) ), ++ SLOT( slotFavDropped( QDropEvent *, QListViewItem * ) ) ); ++ ++ this->installEventFilter(this); ++ m_tabBar->installEventFilter(this); ++ m_favoriteView->installEventFilter(this); ++ m_recentlyView->installEventFilter(this); ++ m_browserView->leftView()->installEventFilter(this); ++ m_browserView->rightView()->installEventFilter(this); ++ m_systemView->installEventFilter(this); ++ m_exitView->leftView()->installEventFilter(this); ++ m_exitView->rightView()->installEventFilter(this); ++ m_kcommand->lineEdit()->installEventFilter(this); ++ m_searchLabel->installEventFilter(this); ++ m_searchPixmap->installEventFilter(this); ++ m_stacker->installEventFilter(this); ++ ++ emailRegExp = QRegExp("^([\\w\\-]+\\.)*[\\w\\-]+@([\\w\\-]+\\.)*[\\w\\-]+$"); ++ authRegExp = QRegExp("^[a-zA-Z]+://\\w+(:\\w+)?@([\\w\\-]+\\.)*[\\w\\-]+(:\\d+)?(/.*)?$"); ++ uriRegExp = QRegExp("^[a-zA-Z]+://([\\w\\-]+\\.)*[\\w\\-]+(:\\d+)?(/.*)?$"); ++ uri2RegExp = QRegExp("^([\\w\\-]+\\.)+[\\w\\-]+(:\\d+)?(/.*)?$"); ++ ++ m_resizeHandle = new QLabel(this); ++ m_resizeHandle->setBackgroundOrigin( QLabel::ParentOrigin ); ++ m_resizeHandle->setScaledContents(true); ++ m_resizeHandle->setFixedSize( 16, 16 ); ++ m_searchFrame->stackUnder( m_resizeHandle ); ++ m_isresizing = false; ++ ++ m_searchPixmap->setPixmap( BarIcon( "find", 32 ) ); ++ ++ QFont f = font(); ++ f.setPointSize( kMax( 7, (f.pointSize() * 4 / 5 ) + KickerSettings::kickoffFontPointSizeOffset() ) ); ++ m_tabBar->setFont ( f ); ++ f.setPointSize( kMax( 7, (f.pointSize() * 3 / 2 ) + KickerSettings::kickoffFontPointSizeOffset() ) ); ++ m_searchLabel->setFont( f ); ++ ++ static_cast(m_kcommand->lineEdit())->setClickMessage(i18n( "Applications, Contacts and Documents" ) ); ++ ++ bookmarkManager = 0; ++ m_addressBook = 0; ++ m_popupMenu = 0; ++ ++ main_border_tl.load( locate("data", "kicker/pics/main_corner_tl.png" ) ); ++ main_border_tr.load( locate("data", "kicker/pics/main_corner_tr.png" ) ); ++ ++ search_tab_left.load( locate("data", "kicker/pics/search-tab-left.png" ) ); ++ search_tab_right.load( locate("data", "kicker/pics/search-tab-right.png" ) ); ++ search_tab_center.load( locate("data", "kicker/pics/search-tab-center.png" ) ); ++ ++ search_tab_top_left.load( locate("data", "kicker/pics/search-tab-top-left.png" ) ); ++ search_tab_top_right.load( locate("data", "kicker/pics/search-tab-top-right.png" ) ); ++ search_tab_top_center.load( locate("data", "kicker/pics/search-tab-top-center.png" ) ); ++} ++ ++void KMenu::setupUi() ++{ ++ m_stacker = new QWidgetStack( this, "m_stacker" ); ++ m_stacker->setGeometry( QRect( 90, 260, 320, 220 ) ); ++ m_stacker->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)3, (QSizePolicy::SizeType)3, 1, 1, m_stacker->sizePolicy().hasHeightForWidth() ) ); ++ m_stacker->setPaletteBackgroundColor( QColor( 255, 255, 255 ) ); ++ // m_stacker->setFocusPolicy( QWidget::StrongFocus ); ++ m_stacker->setLineWidth( 0 ); ++ m_stacker->setFocusPolicy(QWidget::NoFocus); ++ connect(m_stacker, SIGNAL(aboutToShow(QWidget*)), SLOT(stackWidgetRaised(QWidget*))); ++ ++ m_kcommand->setName("m_kcommand"); ++} ++ ++KMenu::~KMenu() ++{ ++ saveConfig(); ++ ++ clearSubmenus(); ++ delete m_filterData; ++} ++ ++bool KMenu::eventFilter ( QObject * receiver, QEvent* e) ++{ ++//kdDebug() << "eventFilter receiver=" << receiver->name() << " type=" << e->type() << endl; ++ QWidget* raiseWidget = 0; ++ QRect raiseRect; ++ ++ if (e->type() == QEvent::KeyPress || ++ e->type() == QEvent::MouseButtonPress || ++ e->type() == QEvent::MouseMove ++ || e->type() == QEvent::FocusIn ++ || e->type() == QEvent::Wheel) { ++ QPoint p; ++ ++ if (e->type() == QEvent::MouseMove || e->type() == QEvent::MouseButtonPress) { ++ QMouseEvent* me = static_cast(e); ++ p = me->globalPos(); ++ } ++ else if (e->type() == QEvent::Wheel) { ++ QWheelEvent* we = static_cast(e); ++ p = we->globalPos(); ++ } ++ ++ while (receiver) { ++ if (receiver == m_tabBar && (e->type()!=QEvent::MouseMove || KickerSettings::kickoffSwitchTabsOnHover() ) ) { ++ QTab* s = m_tabBar->selectTab(m_tabBar->mapFromGlobal(p)); ++ if (s && s->identifier() == ApplicationsTab) ++ raiseWidget = m_browserView; ++ if (s && s->identifier() == FavoriteTab) ++ raiseWidget = m_favoriteView; ++ if (s && s->identifier() == HistoryTab) ++ raiseWidget = m_recentlyView; ++ if (s && s->identifier() == ComputerTab) ++ raiseWidget = m_systemView; ++ if (s && s->identifier() == LeaveTab) ++ raiseWidget = m_exitView; ++ ++ if (raiseWidget) ++ raiseRect = QRect( m_tabBar->mapToGlobal(s->rect().topLeft()), ++ s->rect().size()); ++ } ++ ++ /* we do not want hover activation for the search line edit as this can be ++ * pretty disturbing */ ++ if ( (receiver == m_searchPixmap || ++ ( ( receiver == m_searchLabel || receiver==m_kcommand->lineEdit() ) && ++ ( e->type() == QEvent::KeyPress || e->type() == QEvent::Wheel ++ || e->type() == QEvent::MouseButtonPress ) ) ) && ++ !m_isShowing) { ++ raiseWidget = m_searchWidget; ++ raiseRect = QRect( m_searchFrame->mapToGlobal(m_searchFrame->rect().topLeft()), ++ m_searchFrame->size()); ++ } ++ ++ if(raiseWidget) ++ break; ++ if(receiver->isWidgetType()) ++ receiver = static_cast(receiver)->parentWidget(true); ++ else ++ break; ++ } ++ ++ if (e->type() == QEvent::FocusIn && receiver && raiseWidget) { ++ m_searchResultsWidget->setFocusPolicy(QWidget::StrongFocus); ++ m_searchActions->setFocusPolicy(raiseWidget == m_searchWidget ? ++ QWidget::StrongFocus : QWidget::NoFocus); ++ setTabOrder(raiseWidget, m_searchResultsWidget); ++ if (raiseWidget != m_stacker->visibleWidget() ++ && static_cast(receiver)->focusPolicy() == QWidget::NoFocus ++ && m_stacker->id(raiseWidget) >= 0) { ++ ++ m_stacker->raiseWidget(raiseWidget); ++ return true; ++ } ++ ++ if (raiseWidget->focusPolicy() != QWidget::NoFocus) ++ return false; ++ } ++ ++ if (m_sloppyRegion.contains(p)) { ++ if (e->type() == QEvent::MouseButtonPress /*&& m_sloppyTimer.isActive()*/) ++ m_sloppySourceClicked = true; ++ ++ if (!m_sloppyTimer.isActive() || m_sloppySource != raiseRect) { ++ int timeout= style().styleHint(QStyle::SH_PopupMenu_SubMenuPopupDelay); ++ if (m_sloppySourceClicked) ++ timeout = 3000; ++ m_sloppyTimer.start(timeout); ++ } ++ ++ m_sloppyWidget = raiseWidget; ++ m_sloppySource = raiseRect; ++ return false; ++ } ++ } ++ ++ if(e->type() == QEvent::Enter && receiver->isWidgetType()) { ++ static_cast(receiver)->setMouseTracking(true); ++ QToolTip::hide(); ++ } ++ ++ if ( ( e->type() == QEvent::DragEnter || e->type() == QEvent::DragMove ) && ++ raiseWidget == m_favoriteView ) ++ { ++ m_stacker->raiseWidget(m_favoriteView); ++ ++ return false; ++ } ++ ++ // This is a nightmare of a hack, look away. Logic needs ++ // to be moved to the stacker and all widgets in the stacker ++ // must have focusNextPrevChild() overwritten to do nothing ++ if (e->type() == QEvent::KeyPress && !raiseRect.isNull()) { ++ ItemView* view; ++ if (m_browserView==m_stacker->visibleWidget()) ++ view = m_browserView->currentView(); ++ else if (m_exitView==m_stacker->visibleWidget()) ++ view = m_exitView->currentView(); ++ else ++ view = dynamic_cast(m_stacker->visibleWidget()); ++ ++ if (view) ++ { ++ bool handled = true; ++ switch (static_cast(e)->key()) { ++ case Key_Up: ++ if (view->selectedItem()) { ++ view->setSelected(view->selectedItem()->itemAbove(),true); ++ } ++ else { ++ view->setSelected(view->lastItem(),true); ++ } ++ break; ++ case Key_Down: ++ if (view->selectedItem()) { ++ view->setSelected(view->selectedItem()->itemBelow(),true); ++ } ++ else { ++ if (view->firstChild() && view->firstChild()->isSelectable()) ++ view->setSelected(view->firstChild(),true); ++ else if (view->childCount()>2) ++ view->setSelected(view->firstChild()->itemBelow(),true); ++ } ++ break; ++ case Key_Right: ++ if (view->selectedItem() && !static_cast(view->selectedItem())->hasChildren()) ++ break; ++ // nobreak ++ case Key_Enter: ++ case Key_Return: ++ if (view->selectedItem()) ++ view->slotItemClicked(view->selectedItem()); ++ ++ break; ++ case Key_Left: ++ if (m_browserView == m_stacker->visibleWidget() || m_exitView == m_stacker->visibleWidget()) { ++ FlipScrollView* flip = dynamic_cast(m_stacker->visibleWidget()); ++ if (flip->showsBackButton()) { ++ if (m_browserView == m_stacker->visibleWidget()) ++ goSubMenu( m_browserView->currentView()->backPath(), true ); ++ else ++ view->slotItemClicked(view->firstChild()); ++ } ++ break; ++ } ++ // nobreak ++ case Key_Backspace: ++ if (m_browserView == m_stacker->visibleWidget() || m_exitView == m_stacker->visibleWidget()) { ++ FlipScrollView* flip = dynamic_cast(m_stacker->visibleWidget()); ++ if (flip->showsBackButton()) { ++ if (m_browserView == m_stacker->visibleWidget()) ++ goSubMenu( m_browserView->currentView()->backPath(), true ); ++ else ++ view->slotItemClicked(view->firstChild()); ++ } ++ } ++ ++ break; ++ default: ++ handled = false; ++ } ++ ++ if (handled) ++ view->ensureItemVisible(view->selectedItem()); ++ ++ return handled; ++ } ++ } ++ ++ bool r = KMenuBase::eventFilter(receiver, e); ++ ++ if (!r && raiseWidget) ++ m_stacker->raiseWidget(raiseWidget); ++ ++ if (e->type() == QEvent::Wheel && raiseWidget ) ++ { ++ // due to an ugly Qt bug we have to kill wheel events ++ // that cause focus switches ++ r = true; ++ } ++ ++ if (e->type() == QEvent::Enter && receiver == m_stacker) ++ { ++ QRect r(m_stacker->mapToGlobal(QPoint(-8,-32)), m_stacker->size()); ++ r.setSize(r.size()+QSize(16,128)); ++ ++ m_sloppyRegion = QRegion(r); ++ } ++ ++ // redo the sloppy region ++ if (e->type() == QEvent::MouseMove && !r && raiseWidget) ++ { ++ QPointArray points(4); ++ ++ // hmm, eventually this should be mouse position + 10px, not ++ // just worst case. but worst case seems to work fine enough. ++ QPoint edge(raiseRect.topLeft()); ++ edge.setX(edge.x()+raiseRect.center().x()); ++ ++ if (m_orientation == BottomUp) ++ { ++ points.setPoint(0, m_stacker->mapToGlobal(m_stacker->rect().bottomLeft())); ++ points.setPoint(1, m_stacker->mapToGlobal(m_stacker->rect().bottomRight())); ++ ++ edge.setY(edge.y()+raiseRect.height()); ++ points.setPoint(2, edge+QPoint(+raiseRect.width()/4,0)); ++ points.setPoint(3, edge+QPoint(-raiseRect.width()/4,0)); ++ } ++ else ++ { ++ points.setPoint(0, m_stacker->mapToGlobal(m_stacker->rect().topLeft())); ++ points.setPoint(1, m_stacker->mapToGlobal(m_stacker->rect().topRight())); ++ points.setPoint(2, edge+QPoint(-raiseRect.width()/4,0)); ++ points.setPoint(3, edge+QPoint(+raiseRect.width()/4,0)); ++ } ++ ++ m_sloppyRegion = QRegion(points); ++ } ++ ++ return r; ++} ++ ++void KMenu::slotSloppyTimeout() ++{ ++ if (m_sloppyRegion.contains(QCursor::pos()) && !m_sloppySource.isNull()) ++ { ++ if ( m_sloppySource.contains(QCursor::pos())) ++ { ++ m_stacker->raiseWidget(m_sloppyWidget); ++ ++ m_sloppyWidget = 0; ++ m_sloppySource = QRect(); ++ m_sloppyRegion = QRegion(); ++ m_sloppySourceClicked = false; ++ } ++ } ++ m_sloppyTimer.stop(); ++} ++ ++void KMenu::paintSearchTab( bool active ) ++{ ++ QPixmap canvas( m_searchFrame->size() ); ++ QPainter p( &canvas ); ++ ++ QPixmap pix; ++ ++ if ( m_orientation == BottomUp ) ++ pix.load( locate("data", "kicker/pics/search-gradient.png" ) ); ++ else ++ pix.load( locate("data", "kicker/pics/search-gradient-topdown.png" ) ); ++ ++ pix.convertFromImage( pix.convertToImage().scale(pix.width(), m_searchFrame->height())); ++ p.drawTiledPixmap( 0, 0, m_searchFrame->width(), m_searchFrame->height(), pix ); ++ ++ if ( active ) { ++ ++ m_tabBar->deactivateTabs(true); ++ ++ p.setBrush( Qt::white ); ++ p.setPen( Qt::NoPen ); ++ ++ if ( m_orientation == BottomUp ) { ++ search_tab_center.convertFromImage( search_tab_center.convertToImage().scale(search_tab_center.width(), m_searchFrame->height())); ++ p.drawTiledPixmap( search_tab_left.width(), 0, m_searchFrame->width()-search_tab_left.width()-search_tab_right.width(), m_searchFrame->height(), search_tab_center ); ++ ++ search_tab_left.convertFromImage( search_tab_left.convertToImage().scale(search_tab_left.width(), m_searchFrame->height())); ++ p.drawPixmap( 0, 0, search_tab_left ); ++ ++ search_tab_right.convertFromImage( search_tab_right.convertToImage().scale(search_tab_right.width(), m_searchFrame->height())); ++ p.drawPixmap( m_searchFrame->width()-search_tab_right.width(), 0, search_tab_right ); ++ } ++ else { ++ search_tab_top_center.convertFromImage( search_tab_top_center.convertToImage().scale(search_tab_top_center.width(), m_searchFrame->height())); ++ p.drawTiledPixmap( search_tab_top_left.width(), 0, m_searchFrame->width()-search_tab_top_left.width()-search_tab_top_right.width(), m_searchFrame->height(), search_tab_top_center ); ++ ++ search_tab_top_left.convertFromImage( search_tab_top_left.convertToImage().scale(search_tab_top_left.width(), m_searchFrame->height())); ++ p.drawPixmap( 0, 0, search_tab_top_left ); ++ ++ search_tab_top_right.convertFromImage( search_tab_top_right.convertToImage().scale(search_tab_top_right.width(), m_searchFrame->height())); ++ p.drawPixmap( m_searchFrame->width()-search_tab_top_right.width(), 0, search_tab_top_right ); ++ } ++ } ++ else ++ m_tabBar->deactivateTabs(false); ++ ++ p.end(); ++ m_searchFrame->setPaletteBackgroundPixmap( canvas ); ++} ++ ++void KMenu::stackWidgetRaised(QWidget* raiseWidget) ++{ ++ paintSearchTab(raiseWidget == m_searchWidget); ++ ++ if (raiseWidget == m_browserView) { ++ if ( m_tabBar->currentTab() == ApplicationsTab) ++ slotGoSubMenu(QString::null); ++ if (m_browserDirty ) { ++ createNewProgramList(); ++ m_browserView->prepareRightMove(); ++ m_browserView->currentView()->clear(); ++ fillSubMenu(QString::null, m_browserView->currentView()); ++ m_browserDirty = false; ++ } ++ } ++ else if (raiseWidget == m_recentlyView) { ++ if (m_recentDirty) ++ updateRecent(); ++ } ++ else if (raiseWidget == m_exitView) { ++ if (m_tabBar->currentTab() == LeaveTab) ++ slotGoExitMainMenu(); ++ } ++ ++ ++#warning Qtab fixme ++#if 0 ++ else if (raiseWidget == m_systemView) ++ frame = m_system; ++ else if (raiseWidget == m_favoriteView) ++ frame = m_btnFavorites; ++ if (!frame) ++ return; ++ ++ if ( m_activeTab == frame ) ++ return; ++ ++ paintTab( m_activeTab, false ); ++ paintTab( frame, true ); ++ ++ // if (dynamic_cast(raiseWidget)) ++ // m_activeTab->setFocusProxy(static_cast(raiseWidget)->viewport()); ++ ++ if (0 && /*raiseWidget == m_stacker->visibleWidget() &&*/ !raiseWidget->hasFocus()) { ++ ++ if (dynamic_cast(raiseWidget)) ++ static_cast(raiseWidget)->viewport()->setFocus(); ++ else ++ raiseWidget->setFocus(); ++ } ++ ++ m_activeTab = frame; ++ ++ m_sloppyRegion = QRegion(); ++ m_sloppyTimer.stop(); ++ ++ ItemView* view; ++ if (raiseWidget == m_browserView) ++ view = m_browserView->currentView(); ++ else if (raiseWidget == m_exitView) ++ view = m_exitView->currentView(); ++ else ++ view = dynamic_cast(m_stacker->visibleWidget()); ++ if (view && !view->selectedItem()) { ++ if (view->firstChild() && view->firstChild()->isSelectable()) { ++ view->setSelected(view->firstChild(),true); ++ } ++ else if (view->childCount()>1) { ++ view->setSelected(view->firstChild()->itemBelow(),true); ++ } ++ } ++#endif ++} ++ ++void KMenu::paletteChanged() ++{ ++} ++ ++void KMenu::tabClicked(QTab* t) ++{ ++ if (t==m_tabs[ApplicationsTab]) ++ slotGoSubMenu(QString::null); ++ else if (t==m_tabs[LeaveTab]) ++ slotGoExitMainMenu(); ++} ++ ++void KMenu::slotGoBack() ++{ ++ goSubMenu( m_browserView->currentView()->backPath() ); ++} ++ ++void KMenu::slotGoExitMainMenu() ++{ ++ if (m_exitView->currentView()==m_exitView->rightView()) { ++ m_exitView->prepareLeftMove(false); ++ m_exitView->showBackButton(false); ++ m_exitView->flipScroll(QString::null); ++ } ++} ++ ++void KMenu::slotGoExitSubMenu(const QString& url) ++{ ++ m_exitView->prepareRightMove(); ++ m_exitView->showBackButton(true); ++ ++ int nId = serviceMenuEndId() + 1; ++ int index = 1; ++ ++ if (url=="kicker:/restart/") { ++ QStringList rebootOptions; ++ int def, cur; ++ if ( DM().bootOptions( rebootOptions, def, cur ) ) ++ { ++ if ( cur == -1 ) ++ cur = def; ++ ++ int boot_index = 0; ++ QStringList::ConstIterator it = rebootOptions.begin(); ++ for (; it != rebootOptions.end(); ++it, ++boot_index) ++ { ++ ++ QString option = i18n( "Start '%1'" ).arg( *it ); ++ if (boot_index == cur) ++ option = i18n("Start '%1' (current)").arg( *it ); ++ m_exitView->rightView()->insertItem( "reload", option, ++ i18n( "Restart and boot directly into '%1'").arg( *it ), ++ QString( "kicker:/restart_%1" ).arg( boot_index ), nId++, index++ ); ++ } ++ m_exitView->rightView()->insertHeader( nId++, "kicker:/restart/" ); ++ } ++ } ++ else /*if (url=="kicker:/switchuser/") */{ ++ m_exitView->rightView()->insertItem( "switchuser", i18n( "Start New Session" ), ++ i18n( "Start a parallel session" ), "kicker:/switchuser", nId++, index++ ); ++ ++ m_exitView->rightView()->insertItem( "lock", i18n( "Lock Current && Start New Session").replace("&&","&"), ++ i18n( "Lock screen and start a parallel session" ), "kicker:/switchuserafterlock", nId++, index++ ); ++ ++ SessList sess; ++ if (DM().localSessions( sess )) { ++ if (sess.count()>1) ++ m_exitView->rightView()->insertSeparator( nId++, QString::null, index++ ); ++ for (SessList::ConstIterator it = sess.begin(); it != sess.end(); ++it) { ++ if ((*it).vt && !(*it).self) { ++ QString user, loc; ++ DM().sess2Str2( *it, user, loc ); ++ QStringList list = QStringList::split(":", user); ++ m_exitView->rightView()->insertItem( "switchuser", i18n( "Switch to Session of User '%1'").arg(list[0]), ++ i18n("Session: %1").arg(list[1].mid(1)+", "+loc) , QString("kicker:/switchuser_%1").arg((*it).vt), nId++, index++ ); ++ } ++ } ++ } ++ ++ m_exitView->rightView()->insertHeader( nId++, "kicker:/switchuser/" ); ++ } ++ m_exitView->flipScroll(QString::null); ++} ++ ++void KMenu::slotGoSubMenu(const QString& relPath) ++{ ++ goSubMenu(relPath); ++} ++ ++void KMenu::goSubMenu(const QString& relPath, bool keyboard) ++{ ++ if ( relPath.startsWith( "kicker:/goup/" ) ) ++ { ++ QString rel = relPath.mid( strlen( "kicker:/goup/" ) ); ++ int index = rel.length() - 1; ++ if ( rel.endsWith( "/" ) ) ++ index--; ++ index = rel.findRev( '/', index ); ++ kdDebug() << "goup, rel '" << rel << "' " << index << endl; ++ QString currel = rel; ++ rel = rel.left( index + 1 ); ++ if ( rel == "/" ) ++ rel = QString::null; ++ ++ kdDebug() << "goup, rel '" << rel << "' " << rel.isEmpty() << endl; ++ fillSubMenu( rel, m_browserView->prepareLeftMove() ); ++ m_browserView->flipScroll(keyboard ? currel : QString::null); ++ return; ++ } else if (relPath.isEmpty()) ++ { ++ if (m_browserView->currentView()->path.isEmpty()) ++ return; ++ fillSubMenu( relPath, m_browserView->prepareLeftMove() ); ++ } else if ( relPath.startsWith( "kicker:/new/" ) ) ++ { ++ ItemView* view = m_browserView->prepareRightMove(); ++ m_browserView->showBackButton( true ); ++ ++ int nId = serviceMenuEndId() + 1; ++ view->insertHeader( nId++, "new/" ); ++ int index = 2; ++ for (QStringList::ConstIterator it = m_newInstalledPrograms.begin(); ++ it != m_newInstalledPrograms.end(); ++it) { ++ KService::Ptr p = KService::serviceByStorageId((*it)); ++ view->insertMenuItem(p, nId++, index++); ++ } ++ } else ++ { ++ //m_browserView->clear(); ++ fillSubMenu(relPath, m_browserView->prepareRightMove()); ++ } ++ m_browserView->flipScroll(keyboard ? "kicker:/goup/": QString::null); ++} ++ ++void KMenu::fillSubMenu(const QString& relPath, ItemView *view) ++{ ++ kdDebug() << "fillSubMenu() " << relPath << endl; ++ KServiceGroup::Ptr root = KServiceGroup::group(relPath); ++ Q_ASSERT( root ); ++ ++ KServiceGroup::List list = root->entries(true, true, true, KickerSettings:: ++ menuEntryFormat() == KickerSettings::DescriptionAndName || KickerSettings::menuEntryFormat() ++ == KickerSettings::DescriptionOnly); ++ ++ int nId = serviceMenuStartId(); ++ m_browserView->showBackButton( !relPath.isEmpty() ); ++ if ( !relPath.isEmpty() ) ++ { ++ view->insertHeader( nId++, relPath ); ++ } ++ else if ( m_newInstalledPrograms.count() ) { ++ KMenuItem *item = view->insertItem( "clock", i18n( "New Applications" ), ++ QString::null, "kicker:/new/", nId++, -1 ); ++ item->setHasChildren( true ); ++ view->insertSeparator( nId++, QString::null, -1 ); ++ } ++ ++ view->path = relPath; ++ ++ fillMenu (root, list, relPath, view, nId); ++} ++ ++void KMenu::fillMenu(KServiceGroup::Ptr& ++#ifdef KDELIBS_SUSE ++ _root ++#endif ++ , KServiceGroup::List& _list, ++ const QString& _relPath, ++ ItemView* view, ++ int& id) ++{ ++ bool separatorNeeded = false; ++ KServiceGroup::List::ConstIterator it = _list.begin(); ++#ifdef KDELIBS_SUSE ++ KSortableValueList,QCString> slist; ++ KSortableValueList,QCString> glist; ++ QMap specialTitle; ++ QMap categoryIcon; ++ QMap shortenedMenuPath; ++#endif ++ ++ for (; it != _list.end(); ++it) ++ { ++ KSycocaEntry * e = *it; ++ ++ if (e->isType(KST_KServiceGroup)) ++ { ++ KServiceGroup::Ptr g(static_cast(e)); ++#ifdef KDELIBS_SUSE ++ if ( true /*KickerSettings::reduceMenuDepth()*/ && g->SuSEshortMenu() ){ ++ KServiceGroup::List l = g->entries(true, true /*excludeNoDisplay_*/ ); ++ if ( l.count() == 1 ) { ++ // the special case, we want to short the menu. ++ // TOFIX? : this works only for one level ++ KServiceGroup::List::ConstIterator _it=l.begin(); ++ KSycocaEntry *_e = *_it; ++ if (_e->isType(KST_KService)) { ++ KService::Ptr s(static_cast(_e)); ++ QString key; ++ if ( g->SuSEgeneralDescription() ) { ++ // we use the application name ++ key = s->name(); ++ } ++ else { ++ // we use the normal menu description ++ key = s->name(); ++ if( !s->genericName().isEmpty() && g->caption()!=s->genericName()) { ++ if (KickerSettings::menuEntryFormat() == KickerSettings::NameAndDescription) ++ key = s->name() + " (" + g->caption() + ")"; ++ else if (KickerSettings::menuEntryFormat() == KickerSettings::DescriptionAndName) ++ key = g->caption() + " (" + s->name() + ")"; ++ else if (KickerSettings::menuEntryFormat() == KickerSettings::DescriptionOnly) ++ key = g->caption(); ++ } ++ } ++ specialTitle.insert( _e->name(), key ); ++ categoryIcon.insert( _e->name(), g->icon() ); ++ slist.insert( key.local8Bit(), _e ); ++ shortenedMenuPath.insert( _e->name(), g->relPath() ); ++ // and escape from here ++ continue; ++ } ++ } ++ } ++ glist.insert( g->caption().local8Bit(), e ); ++ }else if( e->isType(KST_KService)) { ++ KService::Ptr s(static_cast(e)); ++ slist.insert( s->name().local8Bit(), e ); ++ } else ++ slist.insert( e->name().local8Bit(), e ); ++ } ++ ++ _list = _root->SuSEsortEntries( slist, glist, true /*excludeNoDisplay_*/, true ); ++ it = _list.begin(); ++ ++ for (; it != _list.end(); ++it) { ++ ++ KSycocaEntry * e = *it; ++ ++ if (e->isType(KST_KServiceGroup)) { ++ ++ KServiceGroup::Ptr g(static_cast(e)); ++ if ( true /*KickerSettings::reduceMenuDepth()*/ && g->SuSEshortMenu() ){ ++ KServiceGroup::List l = g->entries(true, true /*excludeNoDisplay_*/ ); ++ if ( l.count() == 1 ) { ++ continue; ++ } ++ } ++ // standard sub menu ++#endif ++ 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; ++ } ++ ++ bool is_description = KickerSettings::menuEntryFormat() == KickerSettings::DescriptionAndName || ++ KickerSettings::menuEntryFormat() == KickerSettings::DescriptionOnly; ++ ++ QString inlineHeaderName = g->showInlineHeader() ? groupCaption : ""; ++ ++ 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, true, true, is_description ); ++ KSycocaEntry * e1 = *( listElement.begin() ); ++ if ( e1->isType( KST_KService ) ) ++ { ++ KService::Ptr s(static_cast(e1)); ++ view->insertMenuItem(s, id++, -1, 0); ++ 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, true, true, is_description ); ++ ++#if 0 ++ if ( !g->inlineAlias() && !inlineHeaderName.isEmpty() ) ++ { ++ int mid = view->insertItem(new PopupMenuTitle(inlineHeaderName, font()), id++, id, 0); ++ m_browserView->setItemEnabled( mid, false ); ++ } ++#endif ++ ++ fillMenu( rootElement, listElement, g->relPath(), 0, id ); ++ continue; ++ } ++ ++ // Ignore dotfiles. ++ if ((g->name().at(0) == '.')) ++ { ++ continue; ++ } ++ ++ KMenuItem *item = view->insertItem(g->icon(), groupCaption, QString::null, g->relPath(), id++, -1); ++ item->setMenuPath(g->relPath()); ++ item->setHasChildren( true ); ++ ++#warning FIXME ++#if 0 ++ 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(g)); ++ // We have to delete the sub menu our selves! (See Qt docs.) ++ subMenus.append(m); ++#endif ++ } ++ if (e->isType(KST_KService)) ++ { ++ KService::Ptr s(static_cast(e)); ++ if (_relPath.isEmpty()) { ++ QStringList favs = KickerSettings::favorites(); ++ if (favs.find(s->storageId())!=favs.end()) ++ continue; ++ } ++#ifdef KDELIBS_SUSE ++ KMenuItem *item = view->insertMenuItem(s, id++, -1, 0, QString::null, specialTitle[s->name()], categoryIcon[s->name()] ); ++ if (shortenedMenuPath[s->name()].isEmpty()) ++ item->setMenuPath(_relPath+s->menuId()); ++ else ++ item->setMenuPath(shortenedMenuPath[s->name()]+s->menuId()); ++#else ++ KMenuItem *item = view->insertMenuItem(s, id++, -1); ++ item->setMenuPath(_relPath+s->menuId()); ++#endif ++ } ++ else if (e->isType(KST_KServiceSeparator)) ++ { ++ separatorNeeded = true; ++ } ++ } ++ ++ view->slotMoveContent(); ++} ++ ++void KMenu::initialize() ++{ ++ static bool m_initialized=false; ++ if (m_initialized) ++ return; ++ m_initialized = true; ++ ++ kdDebug(1210) << "KMenu::initialize()" << endl; ++ ++ // 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())); ++ ++ /* ++ If the user configured ksmserver to ++ */ ++ KConfig ksmserver("ksmserverrc", false, false); ++ ksmserver.setGroup("General"); ++ connect( m_branding, SIGNAL(clicked()), SLOT(slotOpenHomepage())); ++ m_tabBar->setTabEnabled(LeaveTab, kapp->authorize("logout")); ++ ++ // load search field history ++ QStringList histList = KickerSettings::history(); ++ int maxHistory = KickerSettings::historyLength(); ++ ++ bool block = m_kcommand->signalsBlocked(); ++ m_kcommand->blockSignals( true ); ++ m_kcommand->setMaxCount( maxHistory ); ++ m_kcommand->setHistoryItems( histList ); ++ m_kcommand->blockSignals( block ); ++ ++ QStringList compList = KickerSettings::completionItems(); ++ if( compList.isEmpty() ) ++ m_kcommand->completionObject()->setItems( histList ); ++ else ++ m_kcommand->completionObject()->setItems( compList ); ++ ++ KCompletionBox* box = m_kcommand->completionBox(); ++ if (box) ++ box->setActivateOnSelect( false ); ++ ++ m_finalFilters = KURIFilter::self()->pluginNames(); ++ m_finalFilters.remove("kuriikwsfilter"); ++ ++ m_middleFilters = m_finalFilters; ++ m_middleFilters.remove("localdomainurifilter"); ++ ++ QStringList favs = KickerSettings::favorites(); ++ if (favs.isEmpty()) { ++ QFile f(locate("data", "kicker/default-favs")); ++ if (f.open(IO_ReadOnly)) { ++ QTextStream is(&f); ++ ++ while (!is.eof()) ++ favs << is.readLine(); ++ ++ f.close(); ++ } ++ KickerSettings::setFavorites(favs); ++ KickerSettings::writeConfig(); ++ } ++ ++ int nId = serviceMenuEndId() + 1; ++ int index = 1; ++ for (QStringList::ConstIterator it = favs.begin(); it != favs.end(); ++it) ++ { ++ if ((*it)[0]=='/') { ++ KDesktopFile df((*it),true); ++ QString url = df.readURL(); ++ if (!KURL(url).isLocalFile() || QFile::exists(url.replace("file://",QString::null))) ++ m_favoriteView->insertItem(df.readIcon(),df.readName(),df.readGenericName(), url, nId++, index++); ++ } ++ else { ++ KService::Ptr p = KService::serviceByStorageId((*it)); ++ m_favoriteView->insertMenuItem(p, nId++, index++); ++ } ++ } ++ ++ //nId = m_favoriteView->insertSeparator( nId, QString::null, index++ ); ++// m_favoriteView->insertDocument(KURL("help:/khelpcenter/userguide/index.html"), nId++); ++ ++ insertStaticItems(); ++ ++ m_stacker->raiseWidget (m_favoriteView); ++} ++ ++void KMenu::insertStaticExitItems() ++{ ++ int nId = serviceMenuEndId() + 1; ++ int index = 1; ++ ++ m_exitView->leftView()->insertSeparator( nId++, i18n("Session"), index++ ); ++ if (kapp->authorize("logout")) ++ m_exitView->leftView()->insertItem( "undo", i18n( "Logout" ), ++ i18n( "End session" ), "kicker:/logout", nId++, index++ ); ++ if (kapp->authorize("lock_screen")) ++ m_exitView->leftView()->insertItem( "lock", i18n( "Lock" ), ++ i18n( "Lock screen" ), "kicker:/lock", nId++, index++ ); ++ ++ KConfig ksmserver("ksmserverrc", false, false); ++ ksmserver.setGroup("General"); ++ if (ksmserver.readEntry( "loginMode" ) == "restoreSavedSession") ++ { ++ m_exitView->leftView()->insertItem("filesave", i18n("Save Session"), ++ i18n("Save current Session for next login"), ++ "kicker:/savesession", nId++, index++ ); ++ } ++ if (DM().isSwitchable() && kapp->authorize("switch_user")) ++ { ++ KMenuItem *switchuser = m_exitView->leftView()->insertItem( "switchuser", i18n( "Switch User" ), ++ i18n( "Manage parallel sessions" ), "kicker:/switchuser/", nId++, index++ ); ++ switchuser->setHasChildren(true); ++ } ++ ++ bool maysd = false; ++ if (ksmserver.readBoolEntry( "offerShutdown", true ) && DM().canShutdown()) ++ maysd = true; ++ ++ if ( maysd ) ++ { ++ m_exitView->leftView()->insertSeparator( nId++, i18n("System"), index++ ); ++ m_exitView->leftView()->insertItem( "exit", i18n( "Shutdown Computer" ), ++ i18n( "Turn off computer" ), "kicker:/shutdown", nId++, index++ ); ++ ++ m_exitView->leftView()->insertItem( "reload", i18n( "&Restart Computer" ).replace("&",""), ++ i18n( "Restart and boot the default system" ), ++ "kicker:/restart", nId++, index++ ); ++ ++ insertSuspendOption(nId, index); ++ ++ int def, cur; ++ QStringList dummy_opts; ++ if ( DM().bootOptions( dummy_opts, def, cur ) ) ++ { ++ ++ KMenuItem *restart = m_exitView->leftView()->insertItem( "reload", i18n( "Start Operating System" ), ++ i18n( "Restart and boot another operating system" ), ++ "kicker:/restart/", nId++, index++ ); ++ restart->setHasChildren(true); ++ } ++ } ++} ++ ++void KMenu::insertStaticItems() ++{ ++ insertStaticExitItems(); ++ ++ int nId = serviceMenuEndId() + 10; ++ int index = 1; ++ ++ m_systemView->insertSeparator( nId++, i18n("Applications"), index++); ++ ++ KService::Ptr p = KService::serviceByStorageId("/usr/share/applications/YaST.desktop"); ++ m_systemView->insertMenuItem(p, nId++, index++); ++ ++ m_systemView->insertItem( "info", i18n( "System Information" ), ++ "sysinfo:/", "sysinfo:/", nId++, index++ ); ++ ++ m_systemView->insertSeparator( nId++, i18n("System Folders"), index++ ); ++ ++ m_systemView->insertItem( "folder_home", i18n( "Home Folder" ), ++ QDir::homeDirPath(), "file://"+QDir::homeDirPath(), nId++, index++ ); ++ ++ if ( KStandardDirs::exists( KGlobalSettings::documentPath() + "/" ) ) ++ { ++ QString documentPath = KGlobalSettings::documentPath(); ++ if ( documentPath.endsWith( "/" ) ) ++ documentPath = documentPath.left( documentPath.length() - 1 ); ++ if (documentPath!=QDir::homeDirPath()) ++ m_systemView->insertItem( "folder_man", i18n( "My Documents" ), documentPath, documentPath, nId++, index++ ); ++ } ++ ++ m_systemView->insertItem( "network", i18n( "Network Folders" ), ++ "remote:/", "remote:/", nId++, index++ ); ++ ++ m_mediaWatcher = new MediaWatcher( this ); ++ connect( m_mediaWatcher, SIGNAL( mediumChanged() ), SLOT( updateMedia() ) ); ++ m_media_id = 0; ++ ++ connect(&m_mediaFreeTimer, SIGNAL(timeout()), SLOT( updateMedia())); ++} ++ ++int KMenu::insertClientMenu(KickerClientMenu *) ++{ ++#if 0 ++ int id = client_id; ++ clients.insert(id, p); ++ return id; ++#endif ++ return 0; ++} ++ ++void KMenu::removeClientMenu(int) ++{ ++#if 0 ++ clients.remove(id); ++ slotClear(); ++#endif ++} ++ ++extern int kicker_screen_number; ++ ++void KMenu::slotLock() ++{ ++ kdDebug() << "slotLock " << endl; ++ accept(); ++ QCString appname( "kdesktop" ); ++ if ( kicker_screen_number ) ++ appname.sprintf("kdesktop-screen-%d", kicker_screen_number); ++ kapp->dcopClient()->send(appname, "KScreensaverIface", "lock()", ""); ++} ++ ++void KMenu::slotOpenHomepage() ++{ ++ accept(); ++ kapp->invokeBrowser("http://opensuse.org"); ++} ++ ++void KMenu::slotLogout() ++{ ++ kapp->requestShutDown(); ++} ++ ++void KMenu::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 KMenu::slotSessionActivated( int ent ) ++{ ++ if (ent == 100) ++ doNewSession( true ); ++ else if (ent == 101) ++ doNewSession( false ); ++ else if (!sessionsMenu->isItemChecked( ent )) ++ DM().lockSwitchVT( ent ); ++} ++ ++void KMenu::doNewSession( bool lock ) ++{ ++ int result = KMessageBox::warningContinueCancel( ++ kapp->desktop()->screen(kapp->desktop()->screenNumber(this)), ++ i18n("

You have chosen to open another desktop session.
" ++ "The current session will be hidden " ++ "and a new login screen will be displayed.
" ++ "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.

") ++ .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 KMenu::searchAccept() ++{ ++ QString cmd = m_kcommand->currentText().stripWhiteSpace(); ++ ++ bool logout = (cmd == "logout"); ++ bool lock = (cmd == "lock"); ++ ++ addToHistory(); ++ ++ if ( !logout && !lock ) ++ { ++ // first try if we have any search action ++ if (m_searchResultsWidget->currentItem()) { ++ m_searchResultsWidget->slotItemClicked(m_searchResultsWidget->currentItem()); ++ return; ++ } ++ } ++ ++ accept(); ++ saveConfig(); ++ ++ if ( logout ) ++ { ++ kapp->propagateSessionManager(); ++ kapp->requestShutDown(); ++ } ++ if ( lock ) ++ { ++ QCString appname( "kdesktop" ); ++ int kicker_screen_number = qt_xscreen(); ++ if ( kicker_screen_number ) ++ appname.sprintf("kdesktop-screen-%d", kicker_screen_number); ++ kapp->dcopClient()->send(appname, "KScreensaverIface", "lock()", ""); ++ } ++} ++ ++bool KMenu::runCommand() ++{ ++ kdDebug() << "runCommand() " << m_kcommand->lineEdit()->text() << endl; ++ // Ignore empty commands... ++ if ( m_kcommand->lineEdit()->text().isEmpty() ) ++ return true; ++ ++ accept(); ++ ++ if (input_timer->isActive ()) ++ input_timer->stop (); ++ ++ // Make sure we have an updated data ++ parseLine( true ); ++ ++ bool block = m_kcommand->signalsBlocked(); ++ m_kcommand->blockSignals( true ); ++ m_kcommand->clearEdit(); ++ m_kcommand->setFocus(); ++ m_kcommand->reset(); ++ m_kcommand->blockSignals( block ); ++ ++ ++ QString cmd; ++ KURL uri = m_filterData->uri(); ++ if ( uri.isLocalFile() && !uri.hasRef() && uri.query().isEmpty() ) ++ cmd = uri.path(); ++ else ++ cmd = uri.url(); ++ ++ QString exec; ++ ++ switch( m_filterData->uriType() ) ++ { ++ case KURIFilterData::LOCAL_FILE: ++ case KURIFilterData::LOCAL_DIR: ++ case KURIFilterData::NET_PROTOCOL: ++ case KURIFilterData::HELP: ++ { ++ // No need for kfmclient, KRun does it all (David) ++ (void) new KRun( m_filterData->uri(), parentWidget()); ++ return false; ++ } ++ case KURIFilterData::EXECUTABLE: ++ { ++ if( !m_filterData->hasArgsAndOptions() ) ++ { ++ // Look for desktop file ++ KService::Ptr service = KService::serviceByDesktopName(cmd); ++ if (service && service->isValid() && service->type() == "Application") ++ { ++ notifyServiceStarted(service); ++ KRun::run(*service, KURL::List()); ++ return false; ++ } ++ } ++ } ++ // fall-through to shell case ++ case KURIFilterData::SHELL: ++ { ++ if (kapp->authorize("shell_access")) ++ { ++ exec = cmd; ++ ++ if( m_filterData->hasArgsAndOptions() ) ++ cmd += m_filterData->argsAndOptions(); ++ ++ break; ++ } ++ else ++ { ++ KMessageBox::sorry( this, i18n("
%1
\n" ++ "You do not have permission to execute " ++ "this command.") ++ .arg( QStyleSheet::convertFromPlainText(cmd) )); ++ return true; ++ } ++ } ++ case KURIFilterData::UNKNOWN: ++ case KURIFilterData::ERROR: ++ default: ++ { ++ // Look for desktop file ++ KService::Ptr service = KService::serviceByDesktopName(cmd); ++ if (service && service->isValid() && service->type() == "Application") ++ { ++ notifyServiceStarted(service); ++ KRun::run(*service, KURL::List(), this); ++ return false; ++ } ++ ++ service = KService::serviceByName(cmd); ++ if (service && service->isValid() && service->type() == "Application") ++ { ++ notifyServiceStarted(service); ++ KRun::run(*service, KURL::List(), this); ++ return false; ++ } ++ ++ KMessageBox::sorry( this, i18n("
%1
\n" ++ "Could not run the specified command.") ++ .arg( QStyleSheet::convertFromPlainText(cmd) )); ++ return true; ++ } ++ } ++ ++ if ( KRun::runCommand( cmd, exec, m_iconName ) ) ++ return false; ++ ++ KMessageBox::sorry( this, i18n("
%1
\n" ++ "The specified command does not exist.").arg(cmd) ); ++ return true; // Let the user try again... ++} ++ ++void KMenu::show() ++{ ++ m_isShowing = true; ++ emit aboutToShow(); ++ ++ initialize(); ++ ++ PanelPopupButton *kButton = MenuManager::the()->findKButtonFor( this ); ++ if (kButton) ++ { ++ QPoint center = kButton->center(); ++ QRect screen = QApplication::desktop()->screenGeometry( center ); ++ setOrientation((center.y()-screen.y()raiseWidget(FavoriteTab); ++ m_kcommand->clear(); ++ current_query.clear(); ++ m_kcommand->setFocus(); ++ ++ // we need to reenable it ++ m_toolTipsEnabled = QToolTip::isGloballyEnabled(); ++ QToolTip::setGloballyEnabled(KickerSettings::showToolTips()); ++ ++ KMenuBase::show(); ++ m_isShowing = false; ++} ++ ++void KMenu::setOrientation(MenuOrientation orientation) ++{ ++ if (m_orientation == orientation) ++ return; ++ ++ m_orientation=orientation; ++ ++ m_resizeHandle->setCursor(m_orientation == BottomUp ? Qt::sizeBDiagCursor : Qt::sizeFDiagCursor); ++ ++ QPixmap pix; ++ if ( m_orientation == BottomUp ) ++ pix.load( locate("data", "kicker/pics/search-gradient.png" ) ); ++ else ++ pix.load( locate("data", "kicker/pics/search-gradient-topdown.png" ) ); ++ ++ pix.convertFromImage( pix.convertToImage().scale(pix.width(), m_searchFrame->height())); ++ m_search->mainWidget()->setPaletteBackgroundPixmap( pix ); ++ m_resizeHandle->setPaletteBackgroundPixmap( pix ); ++ ++ m_tabBar->setShape( m_orientation == BottomUp ++ ? QTabBar::RoundedBelow : QTabBar::RoundedAbove); ++ ++ QPixmap respix = QPixmap( locate("data", "kicker/pics/resize_handle.png" ) ); ++ if ( m_orientation == TopDown ) { ++ QWMatrix m; ++ m.rotate( 90.0 ); ++ respix=respix.xForm(m); ++ } ++ m_resizeHandle->setPixmap(respix); ++ ++ { ++ QWidget *footer = m_footer->mainWidget(); ++ QPixmap pix( 64, footer->height() ); ++ QPainter p( &pix ); ++ p.fillRect( 0, 0, 64, footer->height(), m_branding->colorGroup().brush( QColorGroup::Base ) ); ++ p.fillRect( 0, m_orientation == BottomUp ? footer->height() - 2 : 0, ++ 64, 3, KNewButton::self()->borderColor() ); ++ p.end(); ++ footer->setPaletteBackgroundPixmap( pix ); ++ } ++ ++ resizeEvent(new QResizeEvent(sizeHint(), sizeHint())); ++} ++ ++void KMenu::showMenu() ++{ ++ kdDebug() << "KMenu::showMenu()" << endl; ++ PanelPopupButton *kButton = MenuManager::the()->findKButtonFor(this); ++ if (kButton) ++ { ++ adjustSize(); ++ kButton->showMenu(); ++ } ++ else ++ { ++ show(); ++ } ++ kdDebug() << "end KMenu::showMenu()" << endl; ++} ++ ++void KMenu::hide() ++{ ++ //kdDebug() << "KMenu::hide() from " << kdBacktrace() << endl; ++ ++ // TODO: hide popups ++ ++ emit aboutToHide(); ++ ++ if (m_popupMenu) { ++ m_popupMenu->deleteLater(); ++ m_popupMenu=0; ++ } ++ m_mediaFreeTimer.stop(); ++ ++ m_isresizing = false; ++ ++ KickerSettings::setKMenuWidth(width()); ++ KickerSettings::setKMenuHeight(height()); ++ KickerSettings::writeConfig(); ++ ++ QToolTip::setGloballyEnabled(m_toolTipsEnabled); ++ ++ // remove focus from lineedit again, otherwise it doesn't kill its timers ++ m_stacker->raiseWidget(FavoriteTab); ++ ++ QWidget::hide(); ++} ++ ++void KMenu::paintEvent(QPaintEvent * e) ++{ ++ KMenuBase::paintEvent(e); ++ ++ QPainter p(this); ++ p.setClipRegion(e->region()); ++ ++ const BackgroundMode bgmode = backgroundMode(); ++ const QColorGroup::ColorRole crole = QPalette::backgroundRoleFromMode( bgmode ); ++ p.setBrush( colorGroup().brush( crole ) ); ++ ++ p.drawRect( 0, 0, width(), height() ); ++ int ypos = m_search->mainWidget()->geometry().bottom(); ++ ++ p.drawPixmap( 0, ypos, main_border_tl ); ++ p.drawPixmap( width() - main_border_tr.width(), ypos, main_border_tr ); ++ // p.drawPixmap( 0, ->y(), button_box_left ); ++} ++ ++ ++void KMenu::configChanged() ++{ ++ RecentlyLaunchedApps::the().m_bNeedToUpdate = false; ++ RecentlyLaunchedApps::the().configChanged(); ++ ++ m_exitView->leftView()->clear(); ++ insertStaticExitItems(); ++} ++ ++// create and fill "recent" section at first ++void KMenu::createRecentMenuItems() ++{ ++ RecentlyLaunchedApps::the().init(); ++ ++ if (!KickerSettings::numVisibleEntries()) ++ KickerSettings::setNumVisibleEntries(5); ++ ++ int nId = serviceMenuEndId() + 1; ++ m_recentlyView->insertSeparator( nId++, i18n( "Applications" ), -1 ); ++ ++ QStringList RecentApps; ++ ++ if (!KickerSettings::recentVsOften()) { ++ KickerSettings::setRecentVsOften(true); ++ RecentlyLaunchedApps::the().configChanged(); ++ RecentlyLaunchedApps::the().getRecentApps(RecentApps); ++ KickerSettings::setRecentVsOften(false); ++ RecentlyLaunchedApps::the().configChanged(); ++ } ++ else ++ RecentlyLaunchedApps::the().getRecentApps(RecentApps); ++ ++ ++ if (RecentApps.count() > 0) ++ { ++// bool bSeparator = KickerSettings::showMenuTitles(); ++ int nIndex = 0; ++ ++ for (QValueList::ConstIterator it = ++ RecentApps.begin(); it!=RecentApps.end(); ++it) ++ { ++ KService::Ptr s = KService::serviceByStorageId(*it); ++ if (!s) ++ { ++ RecentlyLaunchedApps::the().removeItem(*it); ++ } ++ else ++ m_recentlyView->insertMenuItem(s, nIndex++); ++ } ++ ++ } ++ ++ m_recentlyView->insertSeparator( nId++, i18n( "Documents" ), -1 ); ++ ++ QStringList fileList = KRecentDocument::recentDocuments(); ++ kdDebug() << "createRecentMenuItems=" << fileList << endl; ++ for (QStringList::ConstIterator it = fileList.begin(); ++ it != fileList.end(); ++ ++it) ++ m_recentlyView->insertRecentlyItem(*it, nId++); ++ ++} ++ ++void KMenu::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(); ++} ++ ++void KMenu::updateRecent() ++{ ++ m_recentlyView->clear(); ++ ++ createRecentMenuItems(); ++ ++ m_recentDirty = false; ++} ++ ++void KMenu::popup(const QPoint&, int) ++{ ++ showMenu(); ++} ++ ++void KMenu::clearRecentAppsItems() ++{ ++ RecentlyLaunchedApps::the().clearRecentApps(); ++ RecentlyLaunchedApps::the().save(); ++ RecentlyLaunchedApps::the().m_bNeedToUpdate = true; ++ updateRecent(); ++} ++ ++void KMenu::clearRecentDocsItems() ++{ ++ KRecentDocument::clear(); ++ updateRecent(); ++} ++ ++void KMenu::searchChanged(const QString & text) ++{ ++ if (!text.isEmpty()) { ++ const QColor on = QColor( 244, 244, 244 ); ++ const QColor off = QColor( 181, 181, 181 ); ++ m_stacker->raiseWidget(m_searchWidget); ++ paintSearchTab(true); ++ } ++ ++ m_searchActions->clearSelection(); ++ m_searchResultsWidget->clearSelection(); ++ ++ if (input_timer->isActive ()) ++ input_timer->stop (); ++ input_timer->start (WAIT_BEFORE_QUERYING, TRUE); ++} ++ ++bool KMenu::dontQueryNow (const QString& str) ++{ ++ if (str.isEmpty ()) ++ return true; ++ if (str == current_query.get()) ++ return true; ++ int length = str.length (); ++ int last_whitespace = str.findRev (' ', -1); ++ if (last_whitespace == length-1) ++ return false; // if the user typed a space, search ++ if (last_whitespace >= length-2) ++ return true; // dont search if the user only typed one character ++ QChar lastchar = str[length-1]; ++ if (lastchar == ":" || lastchar == "=") ++ return true; ++ return false; ++} ++ ++void KMenu::createNewProgramList() ++{ ++ m_seenProgramsChanged = false; ++ m_seenPrograms = KickerSettings::firstSeenApps(); ++ m_newInstalledPrograms.clear(); ++ ++ m_currentDate = QDate::currentDate().toString(Qt::ISODate); ++ ++ bool initialize = (m_seenPrograms.count() == 0); ++ ++ createNewProgramList(QString::null); ++ ++ if (initialize) { ++ for (QStringList::Iterator it = m_seenPrograms.begin(); it != m_seenPrograms.end(); ++it) ++ *(++it)="-"; ++ ++ m_newInstalledPrograms.clear(); ++ } ++ ++ if (m_seenProgramsChanged) { ++ KickerSettings::setFirstSeenApps(m_seenPrograms); ++ KickerSettings::writeConfig(); ++ } ++} ++ ++void KMenu::createNewProgramList(QString relPath) ++{ ++ KServiceGroup::Ptr group = KServiceGroup::group(relPath); ++ if (!group || !group->isValid()) ++ return; ++ ++ KServiceGroup::List list = group->entries(); ++ if (list.isEmpty()) ++ return; ++ ++ KServiceGroup::List::ConstIterator it = list.begin(); ++ for(; it != list.end(); ++it) { ++ KSycocaEntry *e = *it; ++ ++ if(e != 0) { ++ if(e->isType(KST_KServiceGroup)) { ++ KServiceGroup::Ptr g(static_cast(e)); ++ if(!g->noDisplay()) ++ createNewProgramList(g->relPath()); ++ } else if(e->isType(KST_KService)) { ++ KService::Ptr s(static_cast(e)); ++ if(s->type() == "Application" && !s->noDisplay() ) { ++ QString shortStorageId = s->storageId().replace(".desktop",QString::null); ++ QStringList::Iterator it_find = m_seenPrograms.begin(); ++ QStringList::Iterator it_end = m_seenPrograms.end(); ++ bool found = false; ++ for (; it_find != it_end; ++it_find) { ++ if (*(it_find)==shortStorageId) { ++ found = true; ++ break; ++ } ++ ++it_find; ++ } ++ if (!found) { ++ m_seenProgramsChanged=true; ++ m_seenPrograms+=shortStorageId; ++ m_seenPrograms+=m_currentDate; ++ if (m_newInstalledPrograms.find(s->storageId())==m_newInstalledPrograms.end()) ++ m_newInstalledPrograms+=s->storageId(); ++ } ++ else { ++ ++it_find; ++ if (*(it_find)!="-") { ++ QDate date = QDate::fromString(*(it_find),Qt::ISODate); ++ if (date.daysTo(QDate::currentDate())<3) { ++ if (m_newInstalledPrograms.find(s->storageId())==m_newInstalledPrograms.end()) ++ m_newInstalledPrograms+=s->storageId(); ++ } ++ else { ++ m_seenProgramsChanged=true; ++ (*it_find)="-"; ++ } ++ } ++ } ++ } ++ } ++ } ++ } ++} ++ ++void KMenu::searchProgramList(QString relPath) ++{ ++ KServiceGroup::Ptr group = KServiceGroup::group(relPath); ++ if (!group || !group->isValid()) ++ return; ++ ++ KServiceGroup::List list = group->entries(); ++ if (list.isEmpty()) ++ return; ++ ++ KServiceGroup::List::ConstIterator it = list.begin(); ++ for(; it != list.end(); ++it) { ++ KSycocaEntry *e = *it; ++ ++ if(e != 0) { ++ if(e->isType(KST_KServiceGroup)) { ++ KServiceGroup::Ptr g(static_cast(e)); ++ if(!g->noDisplay()) ++ searchProgramList(g->relPath()); ++ } else if(e->isType(KST_KService)) { ++ KService::Ptr s(static_cast(e)); ++ if(s->type() == "Application" && !s->noDisplay() && !checkUriInMenu(s->desktopEntryPath())) { ++ if (!current_query.matches(s->name()+' '+s->genericName()+' '+s->exec()+' '+ ++ s->keywords().join(",")+' '+s->comment()+' '+group->caption()+' '+ ++ s->categories().join(",")) || !anotherHitMenuItemAllowed(APPS)) ++ continue; ++ ++ QString input = current_query.get(); ++ int score = 0; ++ if (s->exec()==input) ++ score = 100; ++ else if (s->exec().find(input)==0) ++ score = 50; ++ else if (s->exec().find(input)!=-1) ++ score = 10; ++ else if (s->name().lower()==input) ++ score = 100; ++ else if (s->genericName().lower()==input) ++ score = 100; ++ else if (s->name().lower().find(input)==0) ++ score = 50; ++ else if (s->genericName().lower().find(input)==0) ++ score = 50; ++ else if (s->name().lower().find(input)!=-1) ++ score = 10; ++ else if (s->genericName().lower().find(input)!=-1) ++ score = 10; ++ ++ if (s->exec().find(' ')==-1) ++ score+=1; ++ ++ if (s->substituteUid()) ++ score-=1; ++ ++ if (s->noDisplay()) ++ score -= 100; ++ else if (s->terminal()) ++ score -= 50; ++ else ++ score += kMin(10, s->initialPreference()); ++ ++ QString firstLine, secondLine; ++ if ((KickerSettings::DescriptionAndName || KickerSettings::menuEntryFormat() == KickerSettings::DescriptionOnly) && !s->genericName().isEmpty()) { ++ firstLine = s->genericName(); ++ secondLine = s->name(); ++ } ++ else { ++ firstLine = s->name(); ++ secondLine = s->genericName(); ++ } ++ ++ HitMenuItem *hit_item = new HitMenuItem (firstLine, secondLine, ++ s->desktopEntryPath(), QString::null, 0, APPS, s->icon(), score); ++ if (hit_item == NULL) ++ continue; ++ ++ hit_item->service = s; ++ insertSearchResult(hit_item); ++ ++ QString exe = s->exec(); ++ int pos = exe.find(' '); ++ if (pos>0) ++ exe=exe.left(pos); ++ m_programsInMenu+=KGlobal::dirs()->findExe(exe); ++ } ++ } ++ } ++ } ++} ++ ++void KMenu::searchBookmarks(KBookmarkGroup group) ++{ ++ KBookmark bookmark = group.first(); ++ while(!bookmark.isNull()) { ++ if (bookmark.isGroup()) { ++ searchBookmarks(bookmark.toGroup()); ++ } else if (!bookmark.isSeparator() && !bookmark.isNull()) { ++ if (!current_query.matches(bookmark.fullText()+' '+bookmark.url().url()) || !anotherHitMenuItemAllowed(BOOKMARKS)) { ++ bookmark = group.next(bookmark); ++ continue; ++ } ++ ++ HitMenuItem *hit_item = new HitMenuItem (bookmark.fullText(), bookmark.fullText(), ++ bookmark.url(), QString::null, 0, BOOKMARKS, bookmark.icon()); ++ ++ insertSearchResult(hit_item); ++ } ++ bookmark = group.next(bookmark); ++ } ++} ++ ++void KMenu::initSearch() ++{ ++ if (!m_addressBook && KickerSettings::kickoffSearchAddressBook()) ++ m_addressBook = KABC::StdAddressBook::self( false ); ++ ++ if (!bookmarkManager) ++ bookmarkManager = KBookmarkManager::userBookmarksManager(); ++ ++ if (!m_search_plugin) { ++ m_search_plugin_interface = new QObject( this, "m_search_plugin_interface" ); ++ new MyKickoffSearchInterface( this, m_search_plugin_interface, "kickoffsearch interface" ); ++ KTrader::OfferList offers = KTrader::self()->query("KickoffSearch/Plugin"); ++ ++ KService::Ptr service = *offers.begin(); ++ if (service) { ++ int errCode = 0; ++ m_search_plugin = KParts::ComponentFactory::createInstanceFromService ++ ( service, m_search_plugin_interface, 0, QStringList(), &errCode); ++ } ++ } ++} ++ ++void KMenu::searchAddressbook() ++{ ++ if (!KickerSettings::kickoffSearchAddressBook()) ++ return; ++ ++ if (!m_addressBook) ++ m_addressBook = KABC::StdAddressBook::self( false ); ++ ++ KABC::AddressBook::ConstIterator it = m_addressBook->begin(); ++ while (it!=m_addressBook->end()) { ++ if (!current_query.matches((*it).assembledName()+' '+(*it).fullEmail())) { ++ it++; ++ continue; ++ } ++ ++ HitMenuItem *hit_item; ++ QString realName = (*it).realName(); ++ if (realName.isEmpty()) ++ realName=(*it).preferredEmail(); ++ ++ if (!(*it).preferredEmail().isEmpty()) { ++ if (!anotherHitMenuItemAllowed(ACTIONS)) { ++ it++; ++ continue; ++ } ++ ++ hit_item = new HitMenuItem (i18n("Send Email to %1").arg(realName), (*it).preferredEmail(), ++ "mailto:"+(*it).preferredEmail(), QString::null, 0, ACTIONS, "mail_new"); ++ ++ insertSearchResult(hit_item); ++ } ++ ++ if (!anotherHitMenuItemAllowed(ACTIONS)) { ++ it++; ++ continue; ++ } ++ ++ hit_item = new HitMenuItem (i18n("Open Addressbook at %1").arg(realName), (*it).preferredEmail(), ++ "kaddressbook:/"+(*it).uid(), QString::null, 0, ACTIONS, "kaddressbook"); ++ ++ insertSearchResult(hit_item); ++ ++ it++; ++ } ++} ++ ++QString KMenu::insertBreaks(const QString& text, QFontMetrics fm, int width, QString leadInsert) ++{ ++ QString result, line; ++ QStringList words = QStringList::split(' ', text); ++ ++ for(QStringList::Iterator it = words.begin(); it != words.end(); ++it) { ++ if (fm.width(line+' '+*it) >= width) { ++ if (!result.isEmpty()) ++ result = result + '\n'; ++ result = result + line; ++ line = leadInsert + *it; ++ } ++ else ++ line = line + ' ' + *it; ++ } ++ if (!result.isEmpty()) ++ result = result + '\n'; ++ ++ return result + line; ++} ++ ++void KMenu::clearSearchResults(bool showHelp) ++{ ++ m_searchResultsWidget->clear(); ++ m_searchResultsWidget->setFocusPolicy(showHelp ? QWidget::NoFocus : QWidget::StrongFocus); ++ setTabOrder(m_kcommand, m_searchResultsWidget); ++ ++ if (showHelp) { ++ const int width = m_searchResultsWidget->width()-10; ++ QFontMetrics fm = m_searchResultsWidget->fontMetrics(); ++ ++ QListViewItem* item; ++ item = new QListViewItem( m_searchResultsWidget, insertBreaks(i18n("- Add ext:type to specify a file extension."), fm, width, " ") ); ++ item->setSelectable(false); ++ item->setMultiLinesEnabled(true); ++ item = new QListViewItem( m_searchResultsWidget, insertBreaks(i18n("- When searching for a phrase, add quotes."), fm, width, " " ) ); ++ item->setSelectable(false); ++ item->setMultiLinesEnabled(true); ++ item = new QListViewItem( m_searchResultsWidget, insertBreaks(i18n("- To exclude search terms, use the minus symbol in front."), fm, width, " " ) ); ++ item->setSelectable(false); ++ item->setMultiLinesEnabled(true); ++ item = new QListViewItem( m_searchResultsWidget, insertBreaks(i18n("- To search for optional terms, use OR."), fm, width, " ") ); ++ item->setSelectable(false); ++ item->setMultiLinesEnabled(true); ++ item = new QListViewItem( m_searchResultsWidget, insertBreaks(i18n("- You can use upper and lower case."), fm, width, " ") ); ++ item->setSelectable(false); ++ item->setMultiLinesEnabled(true); ++ item = new QListViewItem( m_searchResultsWidget, i18n("Search Quick Tips")); ++ item->setSelectable(false); ++ } ++ ++ for (int i=0; ilineEdit()->text ().simplifyWhiteSpace (); ++ if (! return_pressed && dontQueryNow (query_str)) { ++ if (query_str.length()<3) ++ clearSearchResults(); ++ else { ++ if (m_searchResultsWidget->firstChild() && m_searchResultsWidget->firstChild()->isSelectable()) { ++ m_searchResultsWidget->setSelected(m_searchResultsWidget->firstChild(),true); ++ } ++ else if (m_searchResultsWidget->childCount()>1) { ++ m_searchResultsWidget->setSelected(m_searchResultsWidget->firstChild()->itemBelow(),true); ++ } ++ } ++ return; ++ } ++ kdDebug() << "Querying for [" << query_str << "]" << endl; ++ current_query.set(query_str); ++ ++ // reset search results ++ HitMenuItem *hit_item; ++ while ((hit_item = m_current_menu_items.take ()) != NULL) { ++ //kndDebug () << " (" << hit_item->id << "," << hit_item->category << ")" << endl; ++ delete hit_item; ++ } ++ ++ clearSearchResults(false); ++ m_searchPixmap->setMovie(QMovie(locate( "data", "kicker/pics/search-running.mng" ))); ++ ++ resetOverflowCategory(); ++ ++ initCategoryTitlesUpdate(); ++ ++ // calculate ? ++ QString cmd = query_str.stripWhiteSpace(); ++ if (!cmd.isEmpty() && (cmd[0].isNumber() || (cmd[0] == '(')) && ++ (QRegExp("[a-zA-Z\\]\\[]").search(cmd) == -1)) ++ { ++ QString result = calculate(cmd); ++ if (!result.isEmpty()) ++ { ++ categorised_hit_total[ACTIONS] ++; ++ HitMenuItem *hit_item = new HitMenuItem (i18n("%1 = %2").arg(query_str, result), QString::null, ++ "kcalc", QString::null, (++max_category_id [ACTIONS]), ACTIONS, "kcalc"); ++ int index = getHitMenuItemPosition (hit_item); ++ m_searchResultsWidget->insertItem(iconForHitMenuItem(hit_item), hit_item->display_name, ++ hit_item->display_info, KGlobal::dirs()->findExe("kcalc"), max_category_id [ACTIONS], index); ++ } ++ } ++ ++ // detect email address ++ if (emailRegExp.exactMatch(query_str)) { ++ categorised_hit_total[ACTIONS] ++; ++ HitMenuItem *hit_item = new HitMenuItem (i18n("Send Email to %1").arg(query_str), QString::null, ++ "mailto:"+query_str, QString::null, (++max_category_id [ACTIONS]), ACTIONS, "mail_new"); ++ int index = getHitMenuItemPosition (hit_item); ++ m_searchResultsWidget->insertItem(iconForHitMenuItem(hit_item), hit_item->display_name, hit_item->display_info, "mailto:"+query_str, max_category_id [ACTIONS], index); ++ } ++ ++ // quick own application search ++ m_programsInMenu.clear(); ++ searchProgramList(QString::null); ++ ++ KURIFilterData filterData; ++ filterData.setData(query_str); ++ filterData.setCheckForExecutables(true); ++ ++ if (KURIFilter::self()->filterURI(filterData)) { ++ ++ QString description; ++ QString exe; ++ ++ switch (filterData.uriType()) { ++ case KURIFilterData::LOCAL_FILE: ++ description = i18n("Open Local File: %1").arg(filterData.uri().url()); ++ break; ++ case KURIFilterData::LOCAL_DIR: ++ description = i18n("Open Local Dir: %1").arg(filterData.uri().url()); ++ break; ++ case KURIFilterData::NET_PROTOCOL: ++ description = i18n("Open Remote Location: %1").arg(filterData.uri().url()); ++ break; ++ case KURIFilterData::SHELL: ++ case KURIFilterData::EXECUTABLE: ++ { ++ exe = KGlobal::dirs()->findExe(filterData.uri().url()); ++#ifdef KDELIBS_SUSE ++ bool gimp_hack = false; ++ if (exe.endsWith("/bin/gimp")) { ++ QStringList::ConstIterator it = m_programsInMenu.begin(); ++ for (; it != m_programsInMenu.end(); ++it) ++ if ((*it).find("bin/gimp-remote-")!=-1) { ++ gimp_hack = true; ++ break; ++ } ++ } ++#endif ++ if (m_programsInMenu.find(exe)!=m_programsInMenu.end() ++#ifdef KDELIBS_SUSE ++ || gimp_hack ++#endif ++ ) ++ exe = QString::null; ++ else if (kapp->authorize("shell_access")) ++ { ++ if( filterData.hasArgsAndOptions() ) ++ exe += filterData.argsAndOptions(); ++ ++ description = i18n("Run '%1'").arg(exe); ++ exe = "kicker:/runcommand"; ++ } ++ } ++ default: ++ break; ++ } ++ ++ if (!description.isEmpty()) { ++ categorised_hit_total[ACTIONS] ++; ++ HitMenuItem *hit_item = new HitMenuItem (description, QString::null, ++ exe.isEmpty() ? filterData.uri() : exe, QString::null, ++ (++max_category_id [ACTIONS]), ACTIONS, exe.isEmpty() ? "fileopen": "run"); ++ int index = getHitMenuItemPosition (hit_item); ++ m_searchResultsWidget->insertItem(iconForHitMenuItem(hit_item), hit_item->display_name, ++ hit_item->display_info, ++ exe.isEmpty() ? filterData.uri().url() : exe, max_category_id [ACTIONS], index); ++ } ++ } ++ ++ // search Konqueror bookmarks; ++ if (!bookmarkManager) ++ bookmarkManager = KBookmarkManager::userBookmarksManager(); ++ ++ if (query_str.length()>=3) ++ searchBookmarks(bookmarkManager->root()); ++ ++ // search KDE addressbook ++ if (query_str.length()>=3) ++ searchAddressbook(); ++ ++ updateCategoryTitles(); ++ ++ if (m_searchResultsWidget->childCount()>1) ++ m_searchResultsWidget->setSelected(m_searchResultsWidget->firstChild()->itemBelow(),true); ++ m_searchActions->clearSelection(); ++ ++ if (!m_search_plugin) ++ initSearch(); ++ ++ // start search plugin only with at least 3 characters ++ if (query_str.length()<3 || !m_search_plugin || (m_search_plugin && !m_search_plugin->daemonRunning()) ) { ++ m_searchPixmap->setPixmap( BarIcon( "find", 32 ) ); ++ fillOverflowCategory(); ++ if (query_str.length()>2 && m_current_menu_items.isEmpty()) ++ reportError (i18n("No matches found")); ++ return; ++ } ++ ++ if (m_search_plugin) { ++ m_search_plugin->query(current_query.get(), KickerSettings::DescriptionAndName || KickerSettings::menuEntryFormat() == KickerSettings::DescriptionOnly); ++ } ++} ++ ++bool KMenu::anotherHitMenuItemAllowed(int cat, bool count) ++{ ++ // update number of hits in this category ++ if (count) ++ categorised_hit_total [cat] ++; ++ ++ // if number of hits in this category is more than allowed, dont process this ++ if (max_category_id [cat] - base_category_id [cat] < max_items(cat)) ++ return true; ++ ++ if (m_overflowCategoryState==None || (m_overflowCategoryState==Filling && m_overflowCategory==cat && ++ max_category_id [cat] + m_overflowList.count() - base_category_id [cat] < max_items(cat) * 2.0)) ++ return true; ++ ++ return false; ++} ++ ++void KMenu::addHitMenuItem(HitMenuItem* item) ++{ ++ if (checkUriInMenu(item->uri)) ++ return; ++ ++ // if number of hits in this category is more than allowed, dont process this ++ if (!anotherHitMenuItemAllowed(item->category, false)) ++ return; ++ ++ insertSearchResult(item); ++} ++ ++void KMenu::insertSearchResult(HitMenuItem* item) ++{ ++ if (m_overflowCategoryState==None) { ++ m_overflowCategoryState = Filling; ++ m_overflowCategory = item->category; ++ } ++ else if (m_overflowCategoryState==Filling && m_overflowCategory!=item->category) ++ m_overflowCategoryState = NotNeeded; ++ ++ if (max_category_id [item->category] - base_category_id [item->category] < max_items(item->category)) { ++ max_category_id [item->category]++; ++ item->id=max_category_id [item->category]; ++ ++ int index = getHitMenuItemPosition (item); ++ ++ kdDebug () << "Adding " << item->uri ++ << "(" << item->mimetype << ") with id=" ++ << max_category_id [item->category] << " at " << index << endl; ++ ++ KMenuItem *hit_item = m_searchResultsWidget->insertItem(iconForHitMenuItem(item), item->display_name, item->display_info, item->uri.url(), max_category_id [item->category], index); ++ hit_item->setService(item->service); ++ ++ kdDebug () << "Done inserting ... " << endl; ++ } ++ else if (m_overflowCategoryState==Filling && m_overflowCategory==item->category && ++ max_category_id [item->category] - base_category_id [item->category] < max_items(item->category) * 2) ++ m_overflowList.append(item); ++} ++ ++void KMenu::searchOver() ++{ ++ m_searchPixmap->setPixmap( BarIcon( "find", 32 ) ); ++ fillOverflowCategory(); ++ if (m_current_menu_items.isEmpty()) { ++ kdDebug() << "No matches found" << endl; ++ reportError (i18n("No matches found")); ++ } ++ if (!m_searchResultsWidget->selectedItem() && !m_searchActions->selectedItem() && m_searchResultsWidget->childCount()>1) { ++ m_searchResultsWidget->setSelected(m_searchResultsWidget->firstChild()->itemBelow(),true); ++ } ++} ++ ++void KMenu::initCategoryTitlesUpdate() ++{ ++ // Need to know if each category was updated with hits or had the first hit ++ // That way we know if we need to changetitle or inserttitle ++ already_added = new bool [num_categories]; ++ for (int i=0; iinsertSeparator(base_category_id [i], title, index); ++ kdDebug () << "Inserting heading with id=" << base_category_id[i] << " for " << categories[i] << " at " << index << endl; ++ } else { ++ // something was already displayed in this category ++ // update the title to reflect the total ++ sep = dynamic_cast( m_searchResultsWidget->findItem(base_category_id [i]) ); ++ if ( !sep ) ++ continue; ++ kdDebug () << "Changing heading of id=" << base_category_id[i] << " for " << categories[i] << endl; ++ } ++ ++ int max = max_items(i); ++ if (m_overflowCategoryState == Filling && m_overflowCategory == i) ++ max *= 2; ++ ++ if ( categorised_hit_total [i] > max ) { ++ if (m_kerryInstalled) ++ sep->setLink( i18n( "top %1 of %2" ).arg( max ).arg( categorised_hit_total [i] ), QString( "kerry:/%1" ).arg( i ) ); ++ else ++ sep->setText( 0, i18n( "%1 (top %2 of %3)" ).arg( i18n(categories [i].utf8()) ).arg( max ).arg( categorised_hit_total [i] ) ); ++ } ++ else { ++ sep->setLink( QString::null ); ++ } ++ } ++ delete[] already_added; ++ already_added = 0; ++} ++ ++QString KMenu::iconForHitMenuItem(HitMenuItem *hit_item) ++{ ++ // get the icon ++ if (!hit_item->icon.isEmpty()) ++ return hit_item->icon; ++ ++ if (hit_item->category == WEBHIST) { ++ QString favicon = KMimeType::favIconForURL (hit_item->uri); ++ if (! favicon.isEmpty ()) ++ return favicon; ++ } ++ ++ if (mimetype_iconstore.contains (hit_item->mimetype)) ++ return (mimetype_iconstore [hit_item->mimetype]); ++ else { ++ KMimeType::Ptr mimetype_ptr = KMimeType::mimeType (hit_item->mimetype); ++ QString mimetype_icon = mimetype_ptr->icon(QString::null, FALSE); ++ mimetype_iconstore [hit_item->mimetype] = mimetype_icon; ++ return mimetype_icon; ++ } ++ return QString::null; ++} ++ ++void KMenu::slotStartService(KService::Ptr ptr) ++{ ++ accept(); ++ ++ addToHistory(); ++ KApplication::startServiceByDesktopPath(ptr->desktopEntryPath(), ++ QStringList(), 0, 0, 0, "", true); ++ updateRecentlyUsedApps(ptr); ++} ++ ++ ++void KMenu::slotStartURL(const QString& u) ++{ ++ if ( u == "kicker:/goup/" ) { ++ // only m_exitView is connected to this slot, not m_browserView ++ slotGoExitMainMenu(); ++ return; ++ } ++ ++ if ( u == "kicker:/restart/" || u=="kicker:/switchuser/") { ++ slotGoExitSubMenu(u); ++ return; ++ } ++ ++ accept(); ++ ++ if ( u == "kicker:/lock" ) { ++ slotLock(); ++ } ++ else if ( u == "kicker:/logout" ) { ++#ifdef KDELIBS_SUSE ++ QByteArray params; ++ QDataStream stream(params, IO_WriteOnly); ++ stream << 0 << -1 << ""; ++ ++ kapp->dcopClient()->send("ksmserver", "default", "logoutTimed(int,int,QString)", params); ++#else ++ DCOPRef mediamanager("ksmserver", "ksmserver"); ++ DCOPReply reply = mediamanager.call( "logoutTimed", (int)KApplication::ShutdownTypeNone, (int)KApplication::ShutdownModeDefault ); ++ if (!reply.isValid() && KMessageBox::Continue==KMessageBox::warningContinueCancel(this, i18n("Do you really want to end the session?"), ++ i18n("Logout Confirmation"), KGuiItem(i18n("Logout"),"undo"))) ++ kapp->requestShutDown( KApplication::ShutdownConfirmNo, ++ KApplication::ShutdownTypeNone, ++ KApplication::ShutdownModeDefault ); ++ ++#endif ++ } ++ else if ( u == "kicker:/runcommand" ) ++ { ++ runCommand(); ++ } ++ else if ( u == "kicker:/shutdown" ) { ++#ifdef KDELIBS_SUSE ++ QByteArray params; ++ QDataStream stream(params, IO_WriteOnly); ++ stream << 2 << -1 << ""; ++ ++ kapp->dcopClient()->send("ksmserver", "default", "logoutTimed(int,int,QString)", params); ++#else ++ if (KMessageBox::Continue==KMessageBox::warningContinueCancel(this, i18n("Do you really want to turn off the computer?"), ++ i18n("Shutdown Confirmation"), KGuiItem(i18n("Shutdown"),"exit"))) ++ kapp->requestShutDown( KApplication::ShutdownConfirmNo, ++ KApplication::ShutdownTypeHalt, ++ KApplication::ShutdownModeDefault ); ++#endif ++ } ++ else if ( u == "kicker:/restart" ) { ++#ifdef KDELIBS_SUSE ++ QByteArray params; ++ QDataStream stream(params, IO_WriteOnly); ++ stream << 1 << -1 << QString::null; ++ ++ kapp->dcopClient()->send("ksmserver", "default", "logoutTimed(int,int,QString)", params); ++#else ++ if (KMessageBox::Continue==KMessageBox::warningContinueCancel(this, i18n("Do you really want to reset the computer and boot (another operating system)?"), ++ i18n("Restart Confirmation"), KGuiItem(i18n("Restart"),"reload"))) ++ kapp->requestShutDown( KApplication::ShutdownConfirmNo, ++ KApplication::ShutdownTypeReboot, ++ KApplication::ShutdownModeDefault ); ++#endif ++ } ++#ifdef KDELIBS_SUSE ++ else if ( u == "kicker:/suspend_disk" ) { ++ slotSuspend( 1 ); ++ } ++ else if ( u == "kicker:/suspend_ram" ) { ++ slotSuspend( 2 ); ++ } ++ else if ( u == "kicker:/standby" ) { ++ slotSuspend( 3 ); ++ } ++#endif ++ else if ( u == "kicker:/savesession" ) { ++ QByteArray data; ++ kapp->dcopClient()->send( "ksmserver", "default", ++ "saveCurrentSession()", data ); ++ } ++ else if ( u == "kicker:/switchuser" ) { ++ DM().startReserve(); ++ } ++ else if ( u == "kicker:/switchuserafterlock" ) { ++ slotLock(); ++ DM().startReserve(); ++ } ++ else if ( u.startsWith("kicker:/switchuser_") ) ++ DM().lockSwitchVT( u.mid(19).toInt() ); ++ else if ( u.startsWith("kicker:/restart_") ) { ++#ifdef KDELIBS_SUSE ++ QStringList rebootOptions; ++ int def, cur; ++ DM().bootOptions( rebootOptions, def, cur ); ++ ++ QByteArray params; ++ QDataStream stream(params, IO_WriteOnly); ++ stream << 1 << -1 << rebootOptions[u.mid(16).toInt()]; ++ ++ kapp->dcopClient()->send("ksmserver", "default", "logoutTimed(int,int,QString)", params); ++#else ++ KMessageBox::error( this, QString( "Sorry, not implemented." )); ++#endif ++ } ++#warning restart entry not supported ++#if 0 ++ else if ( u == "kicker:/restart_windows" ) { ++ if (KMessageBox::Continue==KMessageBox::warningContinueCancel(this, i18n("Do you really want to reset the computer and boot Microsoft Windows"), i18n("Start Windows Confirmation"), KGuiItem(i18n("Start Windows"),"reload"))) ++ KMessageBox::error( this, QString( "kicker:/restart_windows is not yet implemented " ) ); ++ } ++#endif ++ else if ( u.startsWith("kerry:/")) ++ { ++ QByteArray data; ++ QDataStream arg(data, IO_WriteOnly); ++ arg << m_kcommand->currentText() << kerry_categories[u.mid(7).toInt()]; ++ if (ensureServiceRunning("kerry")) ++ kapp->dcopClient()->send("kerry","search","search(QString,QString)", data); ++ } ++ else { ++ addToHistory(); ++ if (u.startsWith("kaddressbook:/")) { ++ KProcess *proc = new KProcess; ++ *proc << "kaddressbook" << "--uid" << u.mid(14); ++ proc->start(); ++ accept(); ++ return; ++ } else if (u.startsWith("note:/")) { ++ KProcess *proc = new KProcess; ++ *proc << "tomboy"; ++ *proc << "--open-note" << u; ++ if (!proc->start()) ++ KMessageBox::error(0,i18n("Could not start Tomboy.")); ++ return; ++ } ++ else if (u.startsWith("knotes:/") ) { ++ if (ensureServiceRunning("knotes")) { ++ QByteArray data; ++ QDataStream arg(data, IO_WriteOnly); ++ arg << u.mid(9,22); ++ ++ kapp->dcopClient()->send("knotes","KNotesIface","showNote(QString)", data); ++ } ++ return; ++ } ++ ++ kapp->propagateSessionManager(); ++ (void) new KRun( u, parentWidget()); ++ } ++} ++ ++void KMenu::slotContextMenuRequested( QListViewItem * item, const QPoint & pos, int /*col*/ ) ++{ ++ const QObject* source = sender(); ++ ++ if (!item) ++ return; ++ ++ KMenuItem* kitem = dynamic_cast(item); ++ if (!kitem) ++ return; ++ ++ KFileItemList _items; ++ _items.setAutoDelete(true); ++ ++ if (dynamic_cast(item)) ++ return; ++ ++ m_popupService = kitem->service(); ++ m_popupPath.menuPath = kitem->menuPath(); ++ if (!m_popupService) { ++ m_popupPath.title = kitem->title(); ++ m_popupPath.description = kitem->description(); ++ m_popupPath.path = kitem->path(); ++ m_popupPath.icon = kitem->icon(); ++ ++ if (m_popupPath.path.startsWith(locateLocal("data", QString::fromLatin1("RecentDocuments/")))) { ++ KDesktopFile df(m_popupPath.path,true); ++ m_popupPath.path=df.readURL(); ++ } ++ } ++ ++ m_popupMenu = new KPopupMenu(this); ++ connect(m_popupMenu, SIGNAL(activated(int)), SLOT(slotContextMenu(int))); ++ bool hasEntries = false; ++ ++ m_popupMenu->insertTitle(SmallIcon(kitem->icon()),kitem->title()); ++ ++ if (source==m_favoriteView) ++ { ++ hasEntries = true; ++ m_popupMenu->insertItem(SmallIconSet("remove"), ++ i18n("Remove From Favorites"), RemoveFromFavorites); ++ } ++ else if (!kitem->hasChildren() && !m_popupPath.path.startsWith("system:/") && ++ !m_popupPath.path.startsWith("kicker:/switchuser_") && !m_popupPath.path.startsWith("kicker:/restart_")) ++ { ++ hasEntries = true; ++ int num = m_popupMenu->insertItem(SmallIconSet("bookmark_add"), ++ i18n("Add to Favorites"), AddToFavorites); ++ ++ QStringList favs = KickerSettings::favorites(); ++ if (m_popupService && favs.find(m_popupService->storageId())!=favs.end()) ++ m_popupMenu->setItemEnabled(num, false); ++ else { ++ QStringList::Iterator it; ++ for (it = favs.begin(); it != favs.end(); ++it) ++ { ++ if ((*it)[0]=='/') ++ { ++ KDesktopFile df((*it),true); ++ if (df.readURL().replace("file://",QString::null)==m_popupPath.path) ++ break; ++ } ++ } ++ if (it!=favs.end()) ++ m_popupMenu->setItemEnabled(num, false); ++ } ++ } ++ ++ if (source!=m_exitView) { ++ if (m_popupService || (!m_popupPath.path.startsWith("kicker:/") && !m_popupPath.path.startsWith("system:/") && !m_popupPath.path.startsWith("kaddressbook:/"))) { ++ if (hasEntries) ++ m_popupMenu->insertSeparator(); ++ ++ if (kapp->authorize("editable_desktop_icons") ) ++ { ++ hasEntries = true; ++ if (m_popupPath.menuPath.endsWith("/")) ++ m_popupMenu->insertItem(SmallIconSet("desktop"), ++ i18n("Add Menu to Desktop"), AddMenuToDesktop); ++ else ++ m_popupMenu->insertItem(SmallIconSet("desktop"), ++ i18n("Add Item to Desktop"), AddItemToDesktop); ++ } ++ if (kapp->authorizeKAction("kicker_rmb") && !Kicker::the()->isImmutable()) ++ { ++ hasEntries = true; ++ if (m_popupPath.menuPath.endsWith("/")) ++ m_popupMenu->insertItem(SmallIconSet("kicker"), ++ i18n("Add Menu to Main Panel"), AddMenuToPanel); ++ else ++ m_popupMenu->insertItem(SmallIconSet("kicker"), ++ i18n("Add Item to Main Panel"), AddItemToPanel); ++ } ++ if (kapp->authorizeKAction("menuedit") && !kitem->menuPath().isEmpty()) ++ { ++ hasEntries = true; ++ if (kitem->menuPath().endsWith("/")) ++ m_popupMenu->insertItem(SmallIconSet("kmenuedit"), i18n("Edit Menu"), EditMenu); ++ else ++ m_popupMenu->insertItem(SmallIconSet("kmenuedit"), i18n("Edit Item"), EditItem); ++ } ++ if (kapp->authorize("run_command") && (m_popupService || (!m_popupPath.menuPath.isEmpty() && !m_popupPath.menuPath.endsWith("/")))) ++ { ++ hasEntries = true; ++ m_popupMenu->insertItem(SmallIconSet("run"), ++ i18n("Put Into Run Dialog"), PutIntoRunDialog); ++ } ++ } ++ if (source==m_searchResultsWidget || ((source==m_favoriteView || source==m_recentlyView || source == m_systemView) && !m_popupService && !m_popupPath.path.startsWith("kicker:/")) ) { ++ QString uri; ++ if (m_popupService) ++ uri = locate("apps", m_popupService->desktopEntryPath()); ++ else ++ uri = m_popupPath.path; ++ ++ QString mimetype = QString::null; ++ if ( m_popupPath.path.startsWith( "system:/media/" ) ) ++ mimetype = media_mimetypes[m_popupPath.path]; ++ ++ KFileItem* item = new KFileItem(uri, mimetype, KFileItem::Unknown); ++ _items.append( item ); ++ ++ const KURL kurl(uri); ++ KActionCollection act(this); ++ ++ KonqPopupMenu * konqPopupMenu = new KonqPopupMenu( KonqBookmarkManager::self(), _items, ++ kurl, act, (KNewMenu*)NULL, this, ++ item->isLocalFile() ? KonqPopupMenu::ShowProperties : KonqPopupMenu::NoFlags, ++ KParts::BrowserExtension::DefaultPopupItems ); ++ ++ if (konqPopupMenu->count()) { ++ if (hasEntries) { ++ m_popupMenu->insertSeparator(); ++ m_popupMenu->insertItem(SmallIconSet("add"),i18n("Advanced"), konqPopupMenu); ++ } ++ else { ++ delete m_popupMenu; ++ m_popupMenu = (KPopupMenu*)konqPopupMenu; ++ m_popupMenu->insertTitle(SmallIcon(kitem->icon()),kitem->title(),-1,0); ++ } ++ hasEntries = true; ++ } ++ } ++ } ++ ++ if (source==m_recentlyView) { ++ m_popupMenu->insertSeparator(); ++ if (m_popupService) ++ m_popupMenu->insertItem(SmallIconSet("history_clear"), ++ i18n("Clear Recently Used Applications"), ClearRecentlyUsedApps); ++ else ++ m_popupMenu->insertItem(SmallIconSet("history_clear"), ++ i18n("Clear Recently Used Documents"), ClearRecentlyUsedDocs); ++ } ++ ++ if (hasEntries) { ++ m_isShowing = true; ++ m_popupMenu->exec(pos); ++ m_isShowing = false; ++ } ++ ++ delete m_popupMenu; ++ m_popupMenu = 0; ++} ++ ++void KMenu::slotContextMenu(int selected) ++{ ++ KServiceGroup::Ptr g; ++ QByteArray ba; ++ QDataStream ds(ba, IO_WriteOnly); ++ ++ KURL src,dest; ++ KIO::CopyJob *job; ++ ++ KProcess *proc; ++ ++ QStringList favs = KickerSettings::favorites(); ++ ++ switch (selected) { ++ case AddItemToDesktop: ++ accept(); ++ if (m_popupService) { ++ src.setPath( KGlobal::dirs()->findResource( "apps", m_popupService->desktopEntryPath() ) ); ++ dest.setPath( KGlobalSettings::desktopPath() ); ++ dest.setFileName( src.fileName() ); ++ ++ job = KIO::copyAs( src, dest ); ++ job->setDefaultPermissions( true ); ++ } ++ else { ++ KDesktopFile* df = new KDesktopFile( newDesktopFile(KURL(m_popupPath.path), KGlobalSettings::desktopPath() ) ); ++ df->writeEntry("GenericName", m_popupPath.description); ++ df->writeEntry( "Icon", m_popupPath.icon ); ++ df->writePathEntry( "URL", m_popupPath.path ); ++ df->writeEntry( "Name", m_popupPath.title ); ++ df->writeEntry( "Type", "Link" ); ++ df->sync(); ++ delete df; ++ } ++ accept(); ++ break; ++ ++ case AddItemToPanel: ++ accept(); ++ if (m_popupService) ++ kapp->dcopClient()->send("kicker", "Panel", "addServiceButton(QString)", m_popupService->desktopEntryPath()); ++ else ++#warning FIXME special RecentDocuments/foo.desktop handling ++ kapp->dcopClient()->send("kicker", "Panel", "addURLButton(QString)", m_popupPath.path); ++ accept(); ++ break; ++ ++ case EditItem: ++ case EditMenu: ++ accept(); ++ proc = new KProcess(this); ++ *proc << KStandardDirs::findExe(QString::fromLatin1("kmenuedit")); ++ *proc << "/"+m_popupPath.menuPath.section('/',-200,-2) << m_popupPath.menuPath.section('/', -1); ++ proc->start(); ++ break; ++ ++ case PutIntoRunDialog: ++ accept(); ++ if (m_popupService) ++ kapp->dcopClient()->send("kdesktop", "default", "popupExecuteCommand(QString)", m_popupService->exec()); ++ else ++#warning FIXME special RecentDocuments/foo.desktop handling ++ kapp->dcopClient()->send("kdesktop", "default", "popupExecuteCommand(QString)", m_popupPath.path); ++ accept(); ++ break; ++ ++ case AddMenuToDesktop: { ++ accept(); ++ KDesktopFile *df = new KDesktopFile( newDesktopFile(KURL("programs:/"+m_popupPath.menuPath),KGlobalSettings::desktopPath())); ++ df->writeEntry( "Icon", m_popupPath.icon ); ++ df->writePathEntry( "URL", "programs:/"+m_popupPath.menuPath ); ++ df->writeEntry( "Name", m_popupPath.title ); ++ df->writeEntry( "Type", "Link" ); ++ df->sync(); ++ delete df; ++ ++ break; ++ } ++ case AddMenuToPanel: ++ accept(); ++ ds << "foo" << m_popupPath.menuPath; ++ kapp->dcopClient()->send("kicker", "Panel", "addServiceMenuButton(QString,QString)", ba); ++ break; ++ ++ case AddToFavorites: ++ if (m_popupService) { ++ if (favs.find(m_popupService->storageId())==favs.end()) { ++ KService::Ptr p = KService::serviceByStorageId(m_popupService->storageId()); ++ m_favoriteView->insertMenuItem(p, serviceMenuEndId()+favs.count()+1); ++ favs+=m_popupService->storageId(); ++ } ++ } ++ else { ++ QStringList::Iterator it; ++ for (it = favs.begin(); it != favs.end(); ++it) { ++ if ((*it)[0]=='/') { ++ KDesktopFile df((*it),true); ++ if (df.readURL().replace("file://",QString::null)==m_popupPath.path) ++ break; ++ } ++ } ++ if (it==favs.end()) { ++ QString file = KickerLib::newDesktopFile(m_popupPath.path); ++ KDesktopFile df(file); ++ df.writeEntry("Encoding", "UTF-8"); ++ df.writeEntry("Type","Link"); ++ df.writeEntry("Name", m_popupPath.title); ++ df.writeEntry("GenericName", m_popupPath.description); ++ df.writeEntry("Icon", m_popupPath.icon); ++ df.writeEntry("URL", m_popupPath.path); ++ ++ m_favoriteView->insertItem(m_popupPath.icon, m_popupPath.title, m_popupPath.description, ++ m_popupPath.path, serviceMenuEndId()+favs.count()+1, -1); ++ ++ favs+=file; ++ } ++ } ++ KickerSettings::setFavorites(favs); ++ KickerSettings::writeConfig(); ++ m_browserDirty=true; ++ m_stacker->raiseWidget(FavoriteTab); ++ break; ++ ++ case RemoveFromFavorites: ++ if (m_popupService) { ++ favs.erase(favs.find(m_popupService->storageId())); ++ ++ for (QListViewItemIterator it(m_favoriteView); it.current(); ++it) { ++ KMenuItem* kitem = static_cast(it.current()); ++ if (kitem->service() && kitem->service()->storageId() == m_popupService->storageId()) { ++ delete it.current(); ++ break; ++ } ++ } ++ } ++ else { ++ for (QStringList::Iterator it = favs.begin(); it != favs.end(); ++it) { ++ if ((*it)[0]=='/') { ++ KDesktopFile df((*it),true); ++ if (df.readURL().replace("file://",QString::null)==m_popupPath.path) { ++ QFile::remove((*it)); ++ favs.erase(it); ++ break; ++ } ++ } ++ } ++ for (QListViewItemIterator it(m_favoriteView); it.current(); ++it) { ++ KMenuItem* kitem = static_cast(it.current()); ++ if (!kitem->service() && kitem->path() == m_popupPath.path) { ++ delete it.current(); ++ break; ++ } ++ } ++ } ++ m_favoriteView->slotMoveContent(); ++ KickerSettings::setFavorites(favs); ++ KickerSettings::writeConfig(); ++ m_browserDirty=true; ++ m_stacker->raiseWidget(FavoriteTab); ++ break; ++ ++ case ClearRecentlyUsedApps: ++ clearRecentAppsItems(); ++ break; ++ ++ case ClearRecentlyUsedDocs: ++ clearRecentDocsItems(); ++ break; ++ ++ default: ++ break; ++ } ++} ++ ++void KMenu::resizeEvent ( QResizeEvent * e ) ++{ ++ //kdDebug() << "resizeEvent " << size() << endl; ++ KMenuBase::resizeEvent(e); ++ int ypos = 0; ++ // this is the height remaining to fill ++ int left_height = height(); ++ ++ if ( m_orientation == BottomUp ) ++ { ++ m_resizeHandle->move( e->size().width() - 19, 3); ++ ++ // put the search widget at the top of the menu and give it its desired ++ // height ++ m_search->mainWidget()->setGeometry( 0, ypos, width(), ++ m_search->minimumSize().height() ); ++ left_height -= m_search->minimumSize().height(); ++ ypos += m_search->minimumSize().height(); ++ ++ // place the footer widget at the bottom of the menu and give it its desired ++ // height ++ m_footer->mainWidget()->setGeometry( 0, height() - m_footer->minimumSize().height(), ++ width(), m_footer->minimumSize().height() ); ++ left_height -= m_footer->minimumSize().height(); ++ ++ // place the button box above the footer widget, horizontal placement ++ // has the width of the edge graphics subtracted ++ m_tabBar->setGeometry(button_box_left.width(), ++ height() - m_footer->minimumSize().height() - ++ m_tabBar->sizeHint().height(), ++ width() - button_box_left.width(), ++ m_tabBar->sizeHint().height() ); ++ left_height -= m_tabBar->sizeHint().height(); ++ ++ // place the main (stacker) widget below the search widget, ++ // in the remaining vertical space ++ m_stacker->setGeometry(0, ypos, ++ width(), ++ left_height ); ++ ++ } ++ else // TopDown orientation ++ { ++ // place the 'footer' widget at the top of the menu and give it ++ // its desired height ++ m_footer->mainWidget()->setGeometry( 0, ++ ypos /*height() - m_footer->minimumSize().height()*/, ++ width(), ++ m_footer->minimumSize().height() ); ++ ypos += m_footer->minimumSize().height(); ++ left_height -= m_footer->minimumSize().height(); ++ ++ // place the button box next at the top of the menu. ++ // has the width of the edge graphics subtracted ++ m_tabBar->setGeometry(button_box_left.width(), ypos, width() - button_box_left.width(), ++ m_tabBar->sizeHint().height()); ++ ++ ypos += m_tabBar->sizeHint().height(); ++ left_height -= m_tabBar->sizeHint().height(); ++ ++ // put the search widget above the footer widget ++ // height ++ m_search->mainWidget()->setGeometry( 0, ++ height() - m_search->minimumSize().height(), ++ width(), ++ m_search->minimumSize().height() ++ ); ++ left_height -= m_search->minimumSize().height(); ++ ++ // place the main (stacker) widget below the button box, ++ // in the remaining vertical space ++ m_stacker->setGeometry(0, ypos, ++ width(), ++ left_height ); ++ m_resizeHandle->move( e->size().width() - 19, e->size().height() - 19); ++ } ++ paintSearchTab( false ); ++} ++ ++void KMenu::mousePressEvent ( QMouseEvent * e ) ++{ ++ if ( m_orientation == BottomUp ) { ++ if (e->x() > width() - m_resizeHandle->width() && ++ e->y() < m_resizeHandle->height() ) ++ { ++ m_isresizing = true; ++ } ++ } ++ else { ++ if (e->x() > width() - m_resizeHandle->width() && ++ e->y() > height() - m_resizeHandle->height() ) ++ { ++ m_isresizing = true; ++ } ++ } ++ KMenuBase::mousePressEvent(e); ++} ++ ++void KMenu::mouseReleaseEvent ( QMouseEvent * /*e*/ ) ++{ ++ m_isresizing = false; ++} ++ ++void KMenu::mouseMoveEvent ( QMouseEvent * e ) ++{ ++ if ( hasMouseTracking() && m_isresizing ) { ++ m_stacker->setMinimumSize( QSize(0, 0) ); ++ m_stacker->setMaximumSize( QSize(32000, 32000) ); ++ int newWidth = QMAX( e->x() - x(), minimumSizeHint().width() ); ++ if ( m_orientation == BottomUp ) { ++ int newHeight = QMAX( height() - e->y(), minimumSizeHint().height() + 10 ); ++ int newY = y() + height() - newHeight; ++ setGeometry( x(), newY, newWidth, newHeight); ++ } ++ else { ++ setGeometry( x(), y(), newWidth, QMAX( e->y(), minimumSizeHint().height() + 10 )); ++ } ++ } ++} ++ ++void KMenu::clearedHistory() ++{ ++ saveConfig(); ++} ++ ++void KMenu::saveConfig() ++{ ++ KickerSettings::setHistory( m_kcommand->historyItems() ); ++ KickerSettings::setCompletionItems( m_kcommand->completionObject()->items() ); ++ KickerSettings::writeConfig(); ++} ++ ++void KMenu::notifyServiceStarted(KService::Ptr service) ++{ ++ // Inform other applications (like the quickstarter applet) ++ // that an application was started ++ QByteArray params; ++ QDataStream stream(params, IO_WriteOnly); ++ stream << "minicli" << service->storageId(); ++ kdDebug() << "minicli appLauncher dcop signal: " << service->storageId() << endl; ++ KApplication::kApplication()->dcopClient()->emitDCOPSignal("appLauncher", ++ "serviceStartedByStorageId(QString,QString)", params); ++} ++ ++void KMenu::parseLine( bool final ) ++{ ++ QString cmd = m_kcommand->currentText().stripWhiteSpace(); ++ m_filterData->setData( cmd ); ++ ++ if( final ) ++ KURIFilter::self()->filterURI( *(m_filterData), m_finalFilters ); ++ else ++ KURIFilter::self()->filterURI( *(m_filterData), m_middleFilters ); ++ ++ m_iconName = m_filterData->iconName(); ++ ++ kdDebug (1207) << "Command: " << m_filterData->uri().url() << endl; ++ kdDebug (1207) << "Arguments: " << m_filterData->argsAndOptions() << endl; ++} ++ ++// report error as a title in the menu ++void KMenu::reportError (QString error) ++{ ++ int index = 1000; //getHitMenuItemPosition (new HitMenuItem (base_category_id[0], 0)); ++ kndDebug () << "Inserting error:" << error << " at position " << index << endl; ++ m_searchResultsWidget->insertSeparator(OTHER_ID_BASE + 120, error, index); ++} ++ ++int KMenu::getHitMenuItemPosition ( HitMenuItem *hit_item) ++{ ++ QPtrListIterator it (m_current_menu_items); ++ const HitMenuItem *cur_item; ++ int pos = 0; ++ while ((cur_item = it.current ()) != NULL) { ++ ++it; ++ if ((cur_item->category!=hit_item->category || !cur_item->display_name.isEmpty()) && (*hit_item) < (*cur_item)) ++ break; ++ pos++; ++ } ++ m_current_menu_items.insert (pos, hit_item); ++ ++ return pos + 1; ++} ++ ++bool KMenu::checkUriInMenu( const KURL &uri) ++{ ++ QPtrListIterator it (m_current_menu_items); ++ const HitMenuItem *cur_item; ++ while ((cur_item = it.current ()) != NULL) { ++ ++it; ++ if (cur_item->uri == uri ) ++ return true; ++ } ++ ++ return false; ++} ++ ++void KMenu::searchActionClicked(QListViewItem* item) ++{ ++ accept(); ++ ++ addToHistory(); ++ if (item==m_searchIndex) { ++ QByteArray data; ++ QDataStream arg(data, IO_WriteOnly); ++ arg << m_kcommand->currentText(); ++ ++ if (ensureServiceRunning("kerry")) ++ kapp->dcopClient()->send("kerry","search","search(QString)", data); ++ } ++ else { ++ KURIFilterData data; ++ QStringList list; ++ data.setData( m_kcommand->currentText() ); ++ list << "kurisearchfilter" << "kuriikwsfilter"; ++ ++ if( !KURIFilter::self()->filterURI(data, list) ) { ++ KDesktopFile file("searchproviders/google.desktop", true, "services"); ++ data.setData(file.readEntry("Query").replace("\\{@}", m_kcommand->currentText())); ++ } ++ ++ (void) new KRun( data.uri(), parentWidget()); ++ } ++} ++ ++void KMenu::addToHistory() ++{ ++ QString search = m_kcommand->currentText().stripWhiteSpace(); ++ ++ if (search.length()<4) ++ return; ++ ++ m_kcommand->addToHistory( search ); ++} ++ ++QString KMenu::newDesktopFile(const KURL& url, const QString &directory) ++{ ++ QString base = url.fileName(); ++ if (base.endsWith(".desktop")) ++ base.truncate(base.length()-8); ++ QRegExp r("(.*)(?=-\\d+)"); ++ if (r.search(base) > -1) ++ base = r.cap(1); ++ ++ QString file = base + ".desktop"; ++ ++ for(int n = 1; ++n; ) ++ { ++ if (!QFile::exists(directory+file)) ++ break; ++ ++ file = QString("%2-%1.desktop").arg(n).arg(base); ++ } ++ return directory+file; ++} ++ ++void KMenu::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; ++} ++ ++QSize KMenu::sizeHint() const ++{ ++#warning FIXME ++ // this should be only for the inner area so layout changes do not break it ++ const int width = kMin(KickerSettings::kMenuWidth(), QApplication::desktop()->screen()->width()-50); ++ ++ const int height = kMin(KickerSettings::kMenuHeight(), QApplication::desktop()->screen()->height()-50); ++ QSize wanted(width, height); ++ kdDebug() << "show " << minimumSizeHint() << " " << m_stacker->minimumSizeHint() << " " ++ << m_searchFrame->minimumSizeHint() << " " << wanted << endl; ++ bool isDefault = wanted.isNull(); ++ wanted = wanted.expandedTo(minimumSizeHint()); ++ if ( isDefault ) ++ wanted.setHeight( wanted.height() + ( m_favoriteView->goodHeight() - m_stacker->minimumSizeHint().height() ) ); ++ ++ return wanted; ++} ++ ++QSize KMenu::minimumSizeHint() const ++{ ++ QSize minsize; ++ minsize.setWidth( minsize.width() + m_tabBar->sizeHint().width() ); ++ minsize.setWidth( QMAX( minsize.width(), ++ m_search->minimumSize().width() ) ); ++ minsize.setWidth( QMAX( minsize.width(), ++ m_search->minimumSize().width() ) ); ++ ++ minsize.setHeight( minsize.height() + ++ m_search->minimumSize().height() + ++ m_footer->minimumSize().height() + ++ 180 ); // 180 is a very rough guess for 32 icon size ++ return minsize; ++} ++ ++void KMenu::slotFavoritesMoved( QListViewItem* item, QListViewItem* /*afterFirst*/, QListViewItem* afterNow) ++{ ++ KMenuItem* kitem = dynamic_cast(item); ++ KMenuItem* kafterNow = dynamic_cast(afterNow); ++ ++ QStringList favs = KickerSettings::favorites(); ++ QStringList::Iterator it; ++ QString addFav = QString::null; ++ ++ // remove at old position ++ if (kitem->service()) ++ { ++ favs.erase(favs.find(kitem->service()->storageId())); ++ addFav = kitem->service()->storageId(); ++ } ++ else ++ { ++ for (it = favs.begin(); it != favs.end(); ++it) ++ { ++ if ((*it)[0]=='/') ++ { ++ KDesktopFile df((*it),true); ++ if (df.readURL().replace("file://",QString::null)==kitem->path()) ++ { ++ addFav = *it; ++ favs.erase(it); ++ break; ++ } ++ } ++ } ++ } ++ ++ if (addFav.isEmpty()) ++ return; ++ ++ if (!kafterNow || dynamic_cast(afterNow)) ++ { ++ favs.prepend(addFav); ++ } ++ else ++ { ++ // add at new position ++ for (it = favs.begin(); it != favs.end(); ++it) ++ { ++ if ((*it)[0]=='/' && !kafterNow->service()) ++ { ++ KDesktopFile df((*it),true); ++ if (df.readURL().replace("file://",QString::null)==kafterNow->path()) ++ { ++ kdDebug() << "insert after " << kafterNow->path() << endl; ++ favs.insert(++it,addFav); ++ break; ++ } ++ } ++ else if (kafterNow->service() && *it==kafterNow->service()->storageId()) ++ { ++ kdDebug() << "insert after service " << kafterNow->service() << endl; ++ favs.insert(++it,addFav); ++ break; ++ } ++ } ++ } ++ kdDebug() << "favs " << favs << endl; ++ ++ KickerSettings::setFavorites(favs); ++ KickerSettings::writeConfig(); ++ ++ m_favoriteView->slotMoveContent(); ++} ++ ++void KMenu::updateMedia() ++{ ++ QStringList devices = m_mediaWatcher->devices(); ++ if ( devices.isEmpty() ) ++ return; ++ ++ int nId = serviceMenuStartId(); ++ if ( m_media_id ) { ++ for ( int i = m_media_id + 1 ;; ++i ) ++ { ++ KMenuItem *item = m_systemView->findItem( i ); ++ if ( !item ) ++ break; ++ if ( !item->path().startsWith( "system:/" ) ) ++ break; ++ media_mimetypes.remove(item->path()); ++ delete item; ++ } ++ nId = m_media_id + 1; ++ } else { ++ m_media_id = nId; ++ m_systemView->insertSeparator( nId++, i18n("Media"), -1); ++ } ++ ++ for ( QStringList::ConstIterator it = devices.constBegin(); it != devices.constEnd(); ++it ) ++ { ++ QString id = ( *it ); ++ QString name = *++it; ++ QString label = *++it; ++ QString userLabel = ( *++it ); ++ bool mountable = ( *++it == "true" ); // bool ++ ( void )mountable; ++ QString deviceNode = ( *++it ); ++ QString mountPoint = ( *++it ); ++ QString fsType = ( *++it ); ++ bool mounted = ( *++it == "true" ); // bool ++ QString baseURL = ( *++it ); ++ QString mimeType = ( *++it ); ++ QString iconName = ( *++it ); ++ ++ media_mimetypes["system:/media/"+name] = mimeType; ++ ++ if ( iconName.isEmpty() ) // no user icon, query the MIME type ++ { ++ KMimeType::Ptr mime = KMimeType::mimeType( mimeType ); ++ iconName = mime->icon( QString::null, false ); ++ } ++ ++ QString descr = deviceNode; ++ if ( mounted ) ++ { ++ descr = mountPoint; ++ // calc the free/total space ++ struct statfs sfs; ++ if ( statfs( QFile::encodeName( mountPoint ), &sfs ) == 0 ) ++ { ++ uint64_t total = ( uint64_t )sfs.f_blocks * sfs.f_bsize; ++ uint64_t avail = ( uint64_t )( getuid() ? sfs.f_bavail : sfs.f_bfree ) * sfs.f_bsize; ++ if ( avail < total && avail > 1024 ) { ++ label += " " + i18n( "(%1 available)" ).arg( KIO::convertSize(avail) ); ++ } ++ } ++ } ++ m_systemView->insertItem( iconName, userLabel.isEmpty() ? label : userLabel, ++ descr, "system:/media/" + name, nId++, -1 ); ++ ++ ++it; // skip separator ++ } ++} ++ ++bool KMenu::ensureServiceRunning(const QString & service) ++{ ++ QStringList URLs; ++ QByteArray data, replyData; ++ QCString replyType; ++ QDataStream arg(data, IO_WriteOnly); ++ arg << service << URLs; ++ ++ if ( !kapp->dcopClient()->call( "klauncher", "klauncher", "start_service_by_desktop_name(QString,QStringList)", ++ data, replyType, replyData) ) { ++ qWarning( "call to klauncher failed."); ++ return false; ++ } ++ QDataStream reply(replyData, IO_ReadOnly); ++ ++ if ( replyType != "serviceResult" ) ++ { ++ qWarning( "unexpected result '%s' from klauncher.", replyType.data()); ++ return false; ++ } ++ int result; ++ QCString dcopName; ++ QString error; ++ reply >> result >> dcopName >> error; ++ if (result != 0) ++ { ++ qWarning("Error starting: %s", error.local8Bit().data()); ++ return false; ++ } ++ return true; ++} ++ ++void KMenu::slotFavDropped(QDropEvent * ev, QListViewItem *after ) ++{ ++ QStringList favs = KickerSettings::favorites(); ++ KMenuItem *newItem = 0; ++ ++ if (KMenuItemDrag::canDecode(ev)) ++ { ++ KMenuItemInfo item; ++ KMenuItemDrag::decode(ev,item); ++ ++ if (item.m_s) ++ { ++ if (favs.find(item.m_s->storageId())==favs.end()) ++ { ++ newItem = m_favoriteView->insertMenuItem(item.m_s, serviceMenuEndId()+favs.count()+1); ++ favs += item.m_s->storageId(); ++ } ++ } ++ else ++ { ++ QString uri = item.m_path; ++ if (uri.startsWith(locateLocal("data", QString::fromLatin1("RecentDocuments/")))) { ++ KDesktopFile df(uri,true); ++ uri=df.readURL(); ++ } ++ ++ QStringList::Iterator it; ++ for (it = favs.begin(); it != favs.end(); ++it) ++ { ++ if ((*it)[0]=='/') ++ { ++ KDesktopFile df((*it),true); ++ if (df.readURL().replace("file://",QString::null)==uri) ++ break; ++ } ++ } ++ if (it==favs.end()) ++ { ++ QString file = KickerLib::newDesktopFile(uri); ++ KDesktopFile df(file); ++ df.writeEntry("Encoding", "UTF-8"); ++ df.writeEntry("Type","Link"); ++ df.writeEntry("Name", item.m_title); ++ df.writeEntry("GenericName", item.m_description); ++ df.writeEntry("Icon", item.m_icon); ++ df.writeEntry("URL", uri); ++ ++ newItem = m_favoriteView->insertItem(item.m_icon, item.m_title, item.m_description, ++ uri, serviceMenuEndId()+favs.count()+1, -1); ++ favs += file; ++ } ++ } ++ } ++ else if (QTextDrag::canDecode(ev)) ++ { ++ QString text; ++ QTextDrag::decode(ev,text); ++ ++ if (text.endsWith(".desktop")) ++ { ++ KService::Ptr p = KService::serviceByDesktopPath(text.replace("file://",QString::null)); ++ if (p && favs.find(p->storageId())==favs.end()) { ++ newItem = m_favoriteView->insertMenuItem(p, serviceMenuEndId()+favs.count()+1); ++ favs+=p->storageId(); ++ } ++ } ++ else ++ { ++ QStringList::Iterator it; ++ for (it = favs.begin(); it != favs.end(); ++it) ++ { ++ if ((*it)[0]=='/') ++ { ++ KDesktopFile df((*it),true); ++ if (df.readURL().replace("file://",QString::null)==text) ++ break; ++ } ++ } ++ if (it==favs.end()) ++ { ++ KFileItem* item = new KFileItem(text, QString::null, KFileItem::Unknown); ++ KURL kurl(text); ++ ++ QString file = KickerLib::newDesktopFile(text); ++ KDesktopFile df(file); ++ df.writeEntry("Encoding", "UTF-8"); ++ df.writeEntry("Type","Link"); ++ df.writeEntry("Name", item->name()); ++ df.writeEntry("GenericName", i18n("Directory: %1").arg(kurl.upURL().path())); ++ df.writeEntry("Icon", item->iconName()); ++ df.writeEntry("URL", text); ++ ++ newItem = m_favoriteView->insertItem(item->iconName(), item->name(), i18n("Directory: %1").arg(kurl.upURL().path()), text, serviceMenuEndId()+favs.count()+1, -1); ++ favs += file; ++ } ++ } ++ } ++ ++ if ( newItem ) { ++ if (!after && m_favoriteView->childCount()>0) { ++ newItem->moveItem( m_favoriteView->firstChild() ); ++ m_favoriteView->firstChild()->moveItem( newItem ); ++ } ++ else ++ newItem->moveItem( after ); ++ KickerSettings::setFavorites(favs); ++ slotFavoritesMoved( newItem, 0, after ); ++ } ++ m_stacker->raiseWidget(m_favoriteView); ++} ++ ++void KMenu::resetOverflowCategory() ++{ ++ if (m_overflowCategoryState==NotNeeded) ++ m_overflowList.setAutoDelete( true ); ++ ++ m_overflowList.clear(); ++ m_overflowList.setAutoDelete( false ); ++ m_overflowCategoryState = None; ++ m_overflowCategory = num_categories; ++} ++ ++void KMenu::fillOverflowCategory() ++{ ++ if (m_overflowCategoryState==Filling) { ++ initCategoryTitlesUpdate(); ++ for (HitMenuItem * item = m_overflowList.first(); item; item = m_overflowList.next() ) { ++ max_category_id [item->category]++; ++ item->id=max_category_id [item->category]; ++ ++ KMenuItem *hit_item = m_searchResultsWidget->insertItem(iconForHitMenuItem(item), item->display_name, item->display_info, item->uri.url(), max_category_id [item->category], getHitMenuItemPosition (item)); ++ hit_item->setService(item->service); ++ } ++ updateCategoryTitles(); ++ } ++} ++ ++int KMenu::max_items(int category) const ++{ ++ if (category==ACTIONS) ++ return 10; ++ ++ return 5; ++} ++ ++#define DBUS_HAL_INTERFACE "org.freedesktop.Hal" ++#define DBUS_HAL_SYSTEM_POWER_INTERFACE "org.freedesktop.Hal.Device.SystemPowerManagement" ++#define HAL_UDI_COMPUTER "/org/freedesktop/Hal/devices/computer" ++ ++#ifdef KDELIBS_SUSE ++#include ++#endif ++ ++void KMenu::insertSuspendOption( int &nId, int &index ) ++{ ++#ifdef KDELIBS_SUSE ++ int supported = -1; ++ bool suspend_ram, suspend_disk, standby; ++ ++ liblazy_hal_get_property_bool(HAL_UDI_COMPUTER, "power_management.can_suspend", &supported); ++ if (supported == 1) ++ suspend_ram = true; ++ else ++ suspend_ram = false; ++ liblazy_hal_get_property_bool(HAL_UDI_COMPUTER, "power_management.can_standby", &supported); ++ if (supported == 1) ++ standby = true; ++ else ++ standby = false; ++ liblazy_hal_get_property_bool(HAL_UDI_COMPUTER, "power_management.can_hibernate", &supported); ++ if (supported == 1) ++ suspend_disk = true; ++ else ++ suspend_disk = false; ++ ++ if (liblazy_hal_is_caller_privileged("org.freedesktop.hal.power-management.hibernate") != 1) ++ suspend_disk = false; ++ if (liblazy_hal_is_caller_privileged("org.freedesktop.hal.power-management.suspend") != 1) ++ suspend_ram = false; ++ if (liblazy_hal_is_caller_privileged("org.freedesktop.hal.power-management.standby") != 1) ++ standby = false; ++ ++ if ( ! ( standby + suspend_ram + suspend_disk ) ) ++ return; ++ ++ i18n("Suspend Computer"); ++ ++ if ( suspend_disk ) ++ m_exitView->leftView()->insertItem( "suspend2disk", i18n( "Suspend to Disk" ), ++ i18n( "Pause without logging out" ), "kicker:/suspend_disk", nId++, index++ ); ++ ++ if ( suspend_ram ) ++ m_exitView->leftView()->insertItem( "suspend2ram", i18n( "Suspend to RAM" ), ++ i18n( "Pause without logging out" ), "kicker:/suspend_ram", nId++, index++ ); ++ ++ if ( standby ) ++ m_exitView->leftView()->insertItem( "player_pause", i18n( "Standby" ), ++ i18n( "Pause without logging out" ), "kicker:/standby", nId++, index++ ); ++#endif ++} ++ ++void KMenu::slotSuspend(int id) ++{ ++#ifdef KDELIBS_SUSE ++ int error = 0; ++ int wake = 0; ++ DBusMessage *reply = 0; ++ ++ if (id == 1) { ++ error = liblazy_dbus_system_send_method_call(DBUS_HAL_INTERFACE, ++ HAL_UDI_COMPUTER, ++ DBUS_HAL_SYSTEM_POWER_INTERFACE, ++ "Hibernate", ++ &reply, ++ DBUS_TYPE_INVALID); ++ } else if (id == 2) ++ error = liblazy_dbus_system_send_method_call(DBUS_HAL_INTERFACE, ++ HAL_UDI_COMPUTER, ++ DBUS_HAL_SYSTEM_POWER_INTERFACE, ++ "Suspend", ++ &reply, ++ DBUS_TYPE_INT32, ++ &wake, ++ DBUS_TYPE_INVALID); ++ else if (id == 3) ++ error = liblazy_dbus_system_send_method_call(DBUS_HAL_INTERFACE, ++ HAL_UDI_COMPUTER, ++ DBUS_HAL_SYSTEM_POWER_INTERFACE, ++ "Standby", ++ &reply, ++ DBUS_TYPE_INVALID); ++ else ++ return; ++ if (error) ++#endif ++ KMessageBox::error(this, i18n("Suspend failed")); ++ ++} ++ ++// vim:cindent:sw=4: +--- kicker/ui/kmenuitembase.ui (Revision 0) ++++ kicker/ui/kmenuitembase.ui (Revision 849791) +@@ -0,0 +1,141 @@ ++ ++KMenuItemBase ++ ++ ++ KMenuItemBase ++ ++ ++ ++ 0 ++ 0 ++ 514 ++ 80 ++ ++ ++ ++ ++ 7 ++ 5 ++ 0 ++ 0 ++ ++ ++ ++ ++ 0 ++ 0 ++ ++ ++ ++ ++ 32767 ++ 80 ++ ++ ++ ++ KMenuItemBase ++ ++ ++ ++ unnamed ++ ++ ++ 2 ++ ++ ++ ++ layout11 ++ ++ ++ ++ unnamed ++ ++ ++ ++ itemTitle ++ ++ ++ ++ 7 ++ 1 ++ 1 ++ 0 ++ ++ ++ ++ ++ 14 ++ ++ ++ ++ ++ ++ ++ RichText ++ ++ ++ WordBreak|AlignTop ++ ++ ++ ++ ++ itemDescription ++ ++ ++ ++ 7 ++ 7 ++ 0 ++ 1 ++ ++ ++ ++ ++ 188 ++ 188 ++ 188 ++ ++ ++ ++ ++ ++ ++ RichText ++ ++ ++ WordBreak|AlignTop ++ ++ ++ ++ ++ ++ ++ layout4 ++ ++ ++ ++ unnamed ++ ++ ++ ++ itemPixmap ++ ++ ++ ++ 64 ++ 64 ++ ++ ++ ++ ++ ++ ++ AlignTop|AlignHCenter ++ ++ ++ ++ ++ ++ ++ ++ +--- kicker/ui/addappletvisualfeedback.cpp (Revision 849788) ++++ kicker/ui/addappletvisualfeedback.cpp (Revision 849791) +@@ -51,6 +51,7 @@ + m_richText(0), + m_dissolveDelta(-1), + m_frames(1), ++ m_moveTimer(0, "m_moveTimer"), + m_dirty(false) + { + setFocusPolicy(NoFocus); +--- kicker/ui/kickoff_bar.cpp (Revision 0) ++++ kicker/ui/kickoff_bar.cpp (Revision 849791) +@@ -0,0 +1,200 @@ ++/***************************************************************** ++ ++ Copyright (c) 1996-2000 the kicker authors. See file AUTHORS. ++ Copyright (c) 2006 Dirk Mueller ++ ++ 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 "kickoff_bar.h" ++#include "itemview.h" ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include "kickerSettings.h" ++ ++KickoffTabBar::KickoffTabBar(QWidget* parent, const char* name) ++ : QTabBar(parent, name), m_tabsActivated(true) ++{ ++ setAcceptDrops(true); ++} ++ ++void KickoffTabBar::deactivateTabs(bool b) ++{ ++ m_tabsActivated = !b; ++ ++ update(); ++} ++ ++void KickoffTabBar::paint(QPainter* p, QTab* t, bool selected) const ++{ ++ QStyle::SFlags flags = QStyle::Style_Default; ++ ++ if (isEnabled() && t->isEnabled()) ++ flags |= QStyle::Style_Enabled; ++ if ( m_tabsActivated && selected ) ++ flags |= QStyle::Style_Selected; ++// else if(t == d->pressed) ++// flags |= QStyle::Style_Sunken; ++ //selection flags ++ if(t->rect().contains(mapFromGlobal(QCursor::pos()))) ++ flags |= QStyle::Style_MouseOver; ++ style().drawControl( QStyle::CE_TabBarTab, p, this, t->rect(), ++ colorGroup(), flags, QStyleOption(t) ); ++ ++ paintLabel( p, t->rect(), t, t->identifier() == keyboardFocusTab() ); ++} ++ ++ ++void KickoffTabBar::paintLabel(QPainter* p, const QRect& br, QTab* t, bool has_focus) const ++{ ++ QRect r = br; ++ ++ bool selected = m_tabsActivated && (currentTab() == t->identifier()); ++ int vframe = style().pixelMetric( QStyle::PM_TabBarTabVSpace, this ); ++ ++ p->setFont( font() ); ++ QFontMetrics fm = p->fontMetrics(); ++ int fw = fm.size( Qt::SingleLine|Qt::ShowPrefix, t->text() ).width(); ++ ++ QRect rt(r); ++ rt.setWidth(fw); ++ ++ if ( t->iconSet()) ++ { ++ // the tab has an iconset, draw it in the right mode ++ QIconSet::Mode mode = (t->isEnabled() && isEnabled()) ++ ? QIconSet::Normal : QIconSet::Disabled; ++ if ( mode == QIconSet::Normal && has_focus ) ++ mode = QIconSet::Active; ++ QPixmap pixmap = t->iconSet()->pixmap( QIconSet::Large, mode ); ++ int pixw = pixmap.width(); ++ int pixh = pixmap.height(); ++ int xoff = br.x() + (br.width() - pixw)/2; ++ int yoff = br.y() + (br.height() - 4 - pixh - ((KickerSettings::kickoffTabBarFormat() != KickerSettings::IconOnly) ? fm.height() : 0) - vframe)/2; ++ ++ p->drawPixmap( xoff, 4 + yoff, pixmap ); ++ ++ r.setTop(vframe/2 + yoff + pixh - 8); ++ rt.setTop(vframe/2 + yoff + pixh - 8); ++ rt.setHeight(((KickerSettings::kickoffTabBarFormat() != KickerSettings::IconOnly) ? fm.height() : 0) + vframe/2); ++ } ++ else ++ rt.setHeight(vframe/2 + fm.height()); ++ ++ rt.setWidth(fw+8); ++ rt.moveCenter(r.center()); ++ ++ QStyle::SFlags flags = QStyle::Style_Default; ++ ++ if (isEnabled() && t->isEnabled()) ++ flags |= QStyle::Style_Enabled; ++ if (has_focus) ++ flags |= QStyle::Style_HasFocus; ++ if ( selected ) ++ flags |= QStyle::Style_Selected; ++ // else if(t == d->pressed) ++ // flags |= QStyle::Style_Sunken; ++ if(t->rect().contains(mapFromGlobal(QCursor::pos()))) ++ flags |= QStyle::Style_MouseOver; ++ style().drawControl( QStyle::CE_TabBarLabel, p, this, rt, ++ t->isEnabled() ? colorGroup(): palette().disabled(), ++ flags, QStyleOption(t) ); ++} ++ ++QSize KickoffTabBar::sizeHint() const ++{ ++ QSize s = QTabBar::sizeHint(); ++ ++ return s; ++} ++ ++void KickoffTabBar::layoutTabs() ++{ ++ QTabBar::layoutTabs(); ++ ++ QFontMetrics fm = fontMetrics(); ++ int fh = ((KickerSettings::kickoffTabBarFormat() != KickerSettings::IconOnly) ? fm.height() : 0) + 4; ++ ++ int hframe = style().pixelMetric( QStyle::PM_TabBarTabHSpace, this ); ++ int vframe = style().pixelMetric( QStyle::PM_TabBarTabVSpace, this ); ++ int overlap = style().pixelMetric( QStyle::PM_TabBarTabOverlap, this ); ++ ++ QSize s; ++ for (int t = 0; t < count(); ++t) ++ { ++ QTab* tab = tabAt(t); ++ if (tab->iconSet()) ++ s = s.expandedTo(tab->iconSet()->pixmap(QIconSet::Large, QIconSet::Normal).size()); ++ } ++ ++ int x = 0; ++ for (int t = 0; t < count(); ++t) { ++ QTab* tab = tabAt(QApplication::reverseLayout() ? count() - t - 1 : t); ++ int h = fh; ++ if (tab->iconSet()) ++ h += 4 + s.height() + 4; ++ QRect r = tab->rect(); ++ ++ int fw = fm.size( Qt::SingleLine|Qt::ShowPrefix, tab->text() ).width(); ++ int iw = 0; ++ if ( tab->iconSet() != 0 ) ++ iw = tab->iconSet()->pixmap( QIconSet::Large, QIconSet::Normal ).width(); ++ int w = QMAX(iw, fw + 6 + 6 ) + hframe; ++ h += ((KickerSettings::kickoffTabBarFormat() != KickerSettings::IconOnly) ? fm.height() : 0) + vframe; ++ tab->setRect(QRect(QPoint(x, 0), style().sizeFromContents(QStyle::CT_TabBarTab, this, ++ QSize(w, h), QStyleOption(tab)))); ++ x += tab->rect().width() - overlap; ++ } ++} ++ ++void KickoffTabBar::dragEnterEvent(QDragEnterEvent* event) ++{ ++ event->accept(KMenuItemDrag::canDecode(event)); ++} ++ ++void KickoffTabBar::dragMoveEvent(QDragMoveEvent* event) ++{ ++ QTab* t = selectTab(event->pos()); ++ ++ // ### uhhh, look away ++ if (t && t->identifier() == 0) ++ { ++ setCurrentTab(t); ++ } ++} ++ ++void KickoffTabBar::mousePressEvent( QMouseEvent * e ) ++{ ++ if ( e->button() != LeftButton ) { ++ e->ignore(); ++ return; ++ } ++ QTab *t = selectTab( e->pos() ); ++ if ( t && t->isEnabled() ) { ++ emit tabClicked(t); ++ } ++ QTabBar::mousePressEvent(e); ++} ++ ++#include "kickoff_bar.moc" ++// vim:cindent:sw=4: +--- kicker/ui/media_watcher.h (Revision 0) ++++ kicker/ui/media_watcher.h (Revision 849791) +@@ -0,0 +1,51 @@ ++/***************************************************************** ++ ++Copyright (c) 2006 Stephan Kulow ++ ++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 _media_watcher_ ++#define _media_watcher_ ++ ++#include ++#include ++#include ++ ++class MediaWatcher : public QObject, public DCOPObject ++{ ++ Q_OBJECT ++ K_DCOP ++ ++ QStringList m_devices; ++ void updateDevices(); ++ ++k_dcop: ++ void slotMediumAdded(QString medium, bool a); ++ ++signals: ++ void mediumChanged(); ++ ++public: ++ MediaWatcher(QObject *parent); ++ ++ QStringList devices() const { return m_devices; } ++}; ++ ++#endif +--- kicker/ui/appletop_mnu.h (Revision 849788) ++++ kicker/ui/appletop_mnu.h (Revision 849791) +@@ -47,6 +47,9 @@ + signals: + void escapePressed(); + ++protected slots: ++ void toggleLegacy(); ++ + protected: + void keyPressEvent(QKeyEvent* e); + }; +--- kicker/ui/flipscrollview.h (Revision 0) ++++ kicker/ui/flipscrollview.h (Revision 849791) +@@ -0,0 +1,118 @@ ++/***************************************************************** ++ ++Copyright (c) 2006 Will Stephenson ++ ++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. ++ ++******************************************************************/ ++ ++/* ++ * Flip scroll menu ++ * Each level of the menu is a separate QListView ++ * Child items are added to their own QListView. ++ * When a parent is clicked, we look up its child menu and insert ++ * that in a QScrollView, then scroll to it. ++ * ++ * Need to intercept QListViewItems' parent param and instead of ++ * inserting directly into parent, insert into parent item's listview ++ * ++ * So need ++ * - adapted QLVI ++ * - wrap QLV and offer same interface ++ */ ++ ++#ifndef FLIPSCROLLVIEW_H ++#define FLIPSCROLLVIEW_H ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include "service_mnu.h" ++ ++class ItemView; ++ ++class BackFrame : public QFrame ++{ ++ Q_OBJECT ++ ++public: ++ BackFrame( QWidget *parent ); ++ virtual void drawContents( QPainter *p ); ++ ++ void enterEvent ( QEvent * ); ++ void leaveEvent( QEvent * ); ++ void mousePressEvent ( QMouseEvent * e ); ++ ++signals: ++ void clicked(); ++ ++private: ++ QPixmap left_triangle; ++ bool mouse_inside; ++}; ++ ++class FlipScrollView : public QScrollView ++{ ++ Q_OBJECT ++public: ++ enum State{ StoppedLeft, StoppedRight, ScrollingLeft, ScrollingRight }; ++ FlipScrollView( QWidget * parent = 0, const char * name = 0 ); ++ ~FlipScrollView(); ++ ++ ItemView *currentView() const; ++ ItemView *leftView() const; ++ ItemView *rightView() const; ++ ItemView *prepareLeftMove(bool clear=true); ++ ItemView *prepareRightMove(); ++ ++ void flipScroll(const QString& selectMenuPath = QString::null); ++ void showBackButton(bool enable); ++ bool showsBackButton() const {return mShowBack;} ++ ++protected slots: ++ void slotScrollTimer(); ++ ++signals: ++ void startService(KService::Ptr kservice); ++ void startURL(const QString& u); ++ void rightButtonPressed(QListViewItem*,const QPoint&,int); ++ void backButtonClicked(); ++ ++protected: ++ void viewportResizeEvent ( QResizeEvent * ); ++ ++private: ++ ItemView * mLeftView; ++ ItemView * mRightView; ++// ItemView * mCurrentView; ++ int mStepsRemaining; ++ State mState; ++ QTimer * mTimer; ++ BackFrame *mBackrow; ++ QString mSelectMenuPath; ++ int mScrollDirection; ++ bool mShowBack; ++}; ++ ++ ++ ++ ++#endif +--- kicker/ui/k_new_mnu.h (Revision 0) ++++ kicker/ui/k_new_mnu.h (Revision 849791) +@@ -0,0 +1,342 @@ ++/***************************************************************** ++ ++ Copyright (c) 1996-2000 the kicker authors. See file AUTHORS. ++ Copyright (c) 2006 Debajyoti Bera ++ ++ 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 __k_new_mnu_h__ ++#define __k_new_mnu_h__ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include "../interfaces/kickoff-search-plugin.h" ++ ++#include "kmenubase.h" ++#include "service_mnu.h" ++#include "query.h" ++ ++class KickerClientMenu; ++class KickoffTabBar; ++class KBookmarkMenu; ++class KActionCollection; ++class KBookmarkOwner; ++class Panel; ++class QWidgetStack; ++class KHistoryCombo; ++class QScrollView; ++class PopupMenuTitle; ++class MediaWatcher; ++class KURIFilterData; ++class KBookmarkGroup; ++class KBookmarkManager; ++class ItemView; ++class FlipScrollView; ++class QListViewItem; ++class KMenuItem; ++class QListView; ++class QTabBar; ++class QTab; ++ ++static QString categories[14] = {I18N_NOOP("Actions"), I18N_NOOP("Applications"), I18N_NOOP("Bookmarks"), ++ I18N_NOOP("Notes"), I18N_NOOP("Emails"), I18N_NOOP("Files"), I18N_NOOP("Music"), ++ I18N_NOOP("Browsing History"), I18N_NOOP("Chat Logs"), I18N_NOOP("Feeds"), ++ I18N_NOOP("Pictures"), I18N_NOOP("Videos"), I18N_NOOP("Documentation"), ++ I18N_NOOP("Others")}; ++ ++static QString kerry_categories[14] = {"contacts", "applications", "webpages", "everything", "conversations", ++ "everything", "media", "webpages", "conversations", "webpages", "images", ++ "media", "everything", "everything"}; ++ ++enum MenuOrientation { BottomUp, TopDown, UnDetermined }; ++enum OverflowCategoryState { None, Filling, NotNeeded }; ++ ++class KMenu : public KMenuBase ++{ ++ Q_OBJECT ++ Q_PROPERTY (bool KStyleMenuDropShadow READ useKStyleMenuDropShadow ) ++ ++public: ++ KMenu(); ++ ~KMenu(); ++ ++ int insertClientMenu(KickerClientMenu *p); ++ void removeClientMenu(int id); ++ ++ bool useKStyleMenuDropShadow() const { return true; } ++ ++ virtual void showMenu(); ++ virtual bool eventFilter(QObject*, QEvent*); ++ ++ void clearRecentAppsItems(); ++ void clearRecentDocsItems(); ++ bool highlightMenuItem(const QString& /*id*/) { return false;} ++ ++ void selectFirstItem() {} ++ void popup(const QPoint&, int indexAtPoint); ++ ++ enum MaskEffect { Plain, Dissolve }; ++ ++ virtual QSize sizeHint() const; ++ virtual QSize minimumSizeHint() const; ++ ++ void searchOver(); ++ void initCategoryTitlesUpdate(); ++ bool anotherHitMenuItemAllowed(int cat, bool count=true); ++ void addHitMenuItem(HitMenuItem*); ++ void insertSearchResult(HitMenuItem* item); ++ ++ void updateCategoryTitles(); ++ ++signals: ++ void aboutToHide(); ++ void aboutToShow(); ++ ++public slots: ++ virtual void initialize(); ++ ++ virtual void hide(); ++ virtual void show(); ++ ++ void stackWidgetRaised(QWidget*); ++ ++protected slots: ++ void slotLock(); ++ void slotOpenHomepage(); ++ void slotLogout(); ++ void slotPopulateSessions(); ++ void slotSessionActivated( int ); ++ void slotGoSubMenu(const QString& relPath); ++ void slotGoBack(); ++ void slotGoExitMainMenu(); ++ void slotGoExitSubMenu(const QString& url); ++ void tabClicked(QTab*); ++ ++ void paletteChanged(); ++ virtual void configChanged(); ++ void updateRecent(); ++ ++ void initSearch(); ++ void searchAccept(); ++ void searchChanged(const QString &); ++ // when timeout happens or doQueryNow calls ++ void doQuery (bool return_pressed = false); ++ void searchActionClicked(QListViewItem*); ++ ++ void slotStartService(KService::Ptr); ++ void slotStartURL(const QString&); ++ void slotContextMenuRequested( QListViewItem * item, const QPoint & pos, int col ); ++ ++ void clearedHistory(); ++ ++ void slotSloppyTimeout(); ++ ++ void slotContextMenu(int); ++ void slotFavoritesMoved( QListViewItem*, QListViewItem*, QListViewItem* ); ++ ++ void updateMedia(); ++ void slotFavDropped(QDropEvent * e, QListViewItem *after ); ++ void slotSuspend(int id); ++ ++protected: ++ virtual void paintEvent(QPaintEvent *); ++ virtual void resizeEvent ( QResizeEvent * ); ++ virtual void mousePressEvent ( QMouseEvent * e ); ++ virtual void mouseReleaseEvent ( QMouseEvent * e ); ++ virtual void mouseMoveEvent ( QMouseEvent * e ); ++ ++ void doNewSession(bool lock); ++ void createRecentMenuItems(); ++ void insertStaticItems(); ++ void insertStaticExitItems(); ++ void insertSuspendOption( int &id, int &index ); ++ virtual void clearSubmenus(); ++// void raiseStackWidget(QWidget *view); ++ ++ bool runCommand(); ++ ++ void setupUi(); ++ ++ void saveConfig(); ++ void searchProgramList(QString relPath); ++ void searchBookmarks(KBookmarkGroup); ++ void searchAddressbook(); ++ ++ void createNewProgramList(); ++ void createNewProgramList(QString relPath); ++ ++ void paintSearchTab( bool active ); ++ ++ void goSubMenu(const QString& relPath, bool keyboard = false); ++ void setOrientation(MenuOrientation orientation); ++ ++private: ++ int serviceMenuStartId() { return 5242; } ++ int serviceMenuEndId() { return 5242; } ++ ++ void fillMenu( KServiceGroup::Ptr &_root, KServiceGroup::List &_list, ++ const QString &_relPath, ItemView* view, int & id ); ++ ++ void fillSubMenu(const QString& relPath, ItemView *view); ++ ++ QPopupMenu *sessionsMenu; ++ int client_id; ++ bool delay_init; ++ QIntDict clients; ++ KActionCollection *actionCollection; ++ PopupMenuList dynamicSubMenus; ++ ++ QTimer m_sloppyTimer; ++ QTimer m_mediaFreeTimer; ++ MediaWatcher * m_mediaWatcher; ++ QRegion m_sloppyRegion; ++ QRect m_sloppySource; ++ bool m_sloppySourceClicked; ++ QWidget * m_sloppyWidget; ++ ItemView * m_recentlyView; ++ ItemView * m_favoriteView; ++ ItemView * m_searchResultsWidget; ++ QListView * m_searchActions; ++ FlipScrollView * m_browserView; ++ ItemView * m_systemView; ++ FlipScrollView * m_exitView; ++ QVBox * m_searchWidget; ++ QLabel * m_resizeHandle; ++ ++ bool m_isresizing; ++ // timer for search without pressing enter feature ++ QTimer *input_timer, *init_search_timer; ++ ++ Query current_query; ++ ++ bool dontQueryNow(const QString &); ++ ++ // start timeout timer to call doQuery is enough time has passed since last keypress ++ void checkToDoQuery (const QString &); ++ // when return is pressed ++ void doQueryNow (); ++ void clearSearchResults(bool showHelp = true); ++ ++ int *max_category_id; // maximum id in this category: max_category_id - base_category_id gives the current number of hits displayed in this category ++ int *categorised_hit_total; // current number of hits returned in each category ++ ++ bool ensureServiceRunning(const QString & service); ++ ++ QString iconForHitMenuItem(HitMenuItem *hit_item); ++ ++ int getHitMenuItemPosition (HitMenuItem *hit_item); ++ QMap mimetype_iconstore; ++ QMap media_mimetypes; ++ // report error as a menu item ++ void reportError (QString err); ++ void addToHistory(); ++ ++ int max_items(int category) const; ++ QString TOP_CATEGORY_STRING; ++ bool *already_added; ++ ++ void notifyServiceStarted(KService::Ptr service); ++ void parseLine( bool final ); ++ QString m_iconName; ++ QStringList m_middleFilters; ++ QStringList m_finalFilters; ++ KURIFilterData* m_filterData; ++ QPtrList m_current_menu_items; ++ QListViewItem *m_searchIndex, *m_searchInternet; ++ ++ bool checkUriInMenu(const KURL &uri); ++ ++ QRegExp emailRegExp,uriRegExp,uri2RegExp,authRegExp; ++ ++ KBookmarkManager *bookmarkManager; ++ KABC::AddressBook* m_addressBook; ++ ++ enum ContextMenuEntry { AddItemToPanel, EditItem, AddMenuToPanel, EditMenu, ++ AddItemToDesktop, AddMenuToDesktop, PutIntoRunDialog, ++ AddToFavorites, RemoveFromFavorites, ClearRecentlyUsedApps, ++ ClearRecentlyUsedDocs }; ++ struct PopupPath ++ { ++ QString title, description, icon, path, menuPath; ++ }; ++ ++ enum KickoffTabEntry { FavoriteTab, ApplicationsTab, ComputerTab, ++ HistoryTab, LeaveTab, SearchTab, NumTabs }; ++ ++ KPopupMenu* m_popupMenu; ++ KService* m_popupService; ++ PopupPath m_popupPath; ++ ++ KickoffTabBar* m_tabBar; ++ QTab* m_tabs[NumTabs]; ++ ++ QString newDesktopFile(const KURL& url, const QString &directory); ++ void updateRecentlyUsedApps(KService::Ptr &service); ++ ++ QPixmap main_border_lc; ++ QPixmap main_border_rc; ++ QPixmap main_border_tl; ++ QPixmap main_border_tr; ++ QPixmap button_box_left; ++ ++ QPixmap search_tab_left; ++ QPixmap search_tab_right; ++ QPixmap search_tab_center; ++ ++ QPixmap search_tab_top_left; ++ QPixmap search_tab_top_right; ++ QPixmap search_tab_top_center; ++ ++ QWidgetStack *m_stacker; ++ ++ QStringList m_programsInMenu; ++ QStringList m_newInstalledPrograms, m_seenPrograms; ++ bool m_seenProgramsChanged; ++ QString m_currentDate; ++ ++ MenuOrientation m_orientation; ++ bool m_toolTipsEnabled; ++ int m_media_id; ++ ++ bool m_recentDirty, m_browserDirty, m_kerryInstalled, m_isShowing; ++ ++ KickoffSearch::Plugin* m_search_plugin; ++ QObject* m_search_plugin_interface; ++ ++ OverflowCategoryState m_overflowCategoryState; ++ QPtrList m_overflowList; ++ int m_overflowCategory; ++ ++ void resetOverflowCategory(); ++ void fillOverflowCategory(); ++ ++ QString insertBreaks(const QString& text, QFontMetrics fm, int width, QString leadInsert = QString::null); ++}; ++ ++#endif +--- kicker/ui/appletop_mnu.cpp (Revision 849788) ++++ kicker/ui/appletop_mnu.cpp (Revision 849791) +@@ -30,6 +30,7 @@ + #include "appletop_mnu.h" + #include "container_button.h" + #include "containerarea.h" ++#include "kickerSettings.h" + + PanelAppletOpMenu::PanelAppletOpMenu(int actions, QPopupMenu *opMenu, const QPopupMenu* appletsMenu, + const QString & title, const QString &icon, +@@ -159,6 +160,20 @@ + } + } + ++ if ((actions & PanelAppletOpMenu::KMenuEditor)) ++ { ++ if (needSeparator) ++ { ++ insertSeparator(); ++ needSeparator = false; ++ } ++ ++ if (KickerSettings::legacyKMenu()) ++ insertItem(SmallIcon("suse"), i18n("Switch to SUSE Menu Style"), this, SLOT(toggleLegacy())); ++ else ++ insertItem(SmallIcon("about_kde"), i18n("Switch to KDE Menu Style"), this, SLOT(toggleLegacy())); ++ } ++ + if ((actions & PanelAppletOpMenu::KMenuEditor) && kapp->authorizeKAction("menuedit")) + { + if (needSeparator) +@@ -205,4 +220,11 @@ + QPopupMenu::keyPressEvent(e); + } + ++void PanelAppletOpMenu::toggleLegacy() ++{ ++ KickerSettings::setLegacyKMenu(!KickerSettings::legacyKMenu()); ++ KickerSettings::writeConfig(); ++ Kicker::the()->restart(); ++} ++ + #include "appletop_mnu.moc" +--- kicker/ui/kmenubase.ui (Revision 0) ++++ kicker/ui/kmenubase.ui (Revision 849791) +@@ -0,0 +1,300 @@ ++ ++KMenuBase ++ ++ ++ KMenu ++ ++ ++ ++ 0 ++ 0 ++ 723 ++ 580 ++ ++ ++ ++ KMenu ++ ++ ++ MShadow ++ ++ ++ MShape ++ ++ ++ ++ m_search ++ ++ ++ ++ 20 ++ 40 ++ 190 ++ 54 ++ ++ ++ ++ ++ unnamed ++ ++ ++ 0 ++ ++ ++ 0 ++ ++ ++ ++ m_searchFrame ++ ++ ++ ++ 5 ++ 0 ++ 0 ++ 0 ++ ++ ++ ++ ++ 0 ++ 52 ++ ++ ++ ++ ++ 32767 ++ 52 ++ ++ ++ ++ StyledPanel ++ ++ ++ Raised ++ ++ ++ 0 ++ ++ ++ ++ unnamed ++ ++ ++ ++ layout18 ++ ++ ++ ++ unnamed ++ ++ ++ ++ m_searchLabel ++ ++ ++ ParentOrigin ++ ++ ++ ++ 14 ++ ++ ++ ++ Search: ++ ++ ++ ++ ++ m_kcommand ++ ++ ++ ++ 7 ++ 0 ++ 0 ++ 0 ++ ++ ++ ++ ++ ++ m_searchPixmap ++ ++ ++ ++ 1 ++ 1 ++ 0 ++ 0 ++ ++ ++ ++ ++ 32 ++ 32 ++ ++ ++ ++ ++ 32 ++ 32 ++ ++ ++ ++ PaletteBackground ++ ++ ++ ParentOrigin ++ ++ ++ true ++ ++ ++ ++ ++ ++ ++ ++ ++ spacer5_2 ++ ++ ++ Horizontal ++ ++ ++ Preferred ++ ++ ++ ++ 16 ++ 20 ++ ++ ++ ++ ++ ++ ++ ++ m_footer ++ ++ ++ ++ 20 ++ 110 ++ 407 ++ 34 ++ ++ ++ ++ ++ unnamed ++ ++ ++ 4 ++ ++ ++ 4 ++ ++ ++ ++ m_userInfo ++ ++ ++ ++ 3 ++ 0 ++ 0 ++ 0 ++ ++ ++ ++ User&nbsp;<b>user</b>&nbsp;on&nbsp;<b>host</b> ++ ++ ++ ++ ++ spacer13_2 ++ ++ ++ Horizontal ++ ++ ++ MinimumExpanding ++ ++ ++ ++ 10 ++ 20 ++ ++ ++ ++ ++ ++ m_branding ++ ++ ++ ++ 4 ++ 4 ++ 0 ++ 0 ++ ++ ++ ++ ++ 90 ++ 24 ++ ++ ++ ++ ++ ++ ++ image0 ++ ++ ++ true ++ ++ ++ true ++ ++ ++ ++ ++ spacer13 ++ ++ ++ Horizontal ++ ++ ++ Fixed ++ ++ ++ ++ 14 ++ 20 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ 789cdd933d6fdb30104077ff0a21de8c82b12d5bb2507448f6021d0b141dc82369d9116d7d50b1ada2ffbdbca3c4444950244032b4b790efce7cd29de8eb59f4fddbd768763d692cb73b8820e7753493ad31971f3fbffc9a5c6d36d17219c5f36871f56972e57e104dd7324be325a2464cd24cc60a5120a6731eaf046241c879b64e113bc44dcc751223da802bc41de16ac092508a753a4754885922440a8892301332a5e79e10f91c169b0cf1963083345b231a423ee0bec78dc71c51c420393578249432e664be2354d2bd17628d0889cc0447bc20cab9d490205601a9df29e142cd3d9e0933b59234ba0321576b49d3d8f69878bc41544b952a6abf218c9590f41a9c70a5c0e33d21e885a2e1b4883ad1a9de2032420ac20f8affde3df5415bdea7f8b8c0fbed507fa59b0bf02119739f9172b46e755fc819dbf55bd07ba15fef0ec7f6b41f728c0dcf84bbc76ebedfbfde0d2042eb8fdd5b801de5b794281e06f716f7ee710f619d5227a1b01b1d0aeedc18e366660ec7b2ac18ab1d1a9745acd1ad3161f28631dbbb716d86c29112c2f86363770ec20a383a89b51a9a06b4b5503a2c10dd771b46d98cdcac180a052528cc13b781b6bd7759506d5b435541ddb6161cba16c0f5a174383872b3729057c19dbfe06ed16ddab642b7324638b77b870add3eaae76e1fb577db17e7fdcc5d586bcd5fddc59bdda7deed7d83db580a81ee93bb906eefd4ee0fa24201ddda53f9d4ad4ce92605fae466713843614ceddd17b83008d1b06618bd2b5e42de3da70b7019dfc1b2eb3af7e140a9ae7342d3d152babb75ee1a76ea7c9478ea5c92bd3bf6c7a870f6677cdc8cdd7d840bf40ef1cc7dfb716efd81eef78c7fd6fdfbf3e40f51236246 ++ ++ ++ ++ kmenubase.ui.h ++ ++ ++ init() ++ ++ ++ ++ kcombobox.h ++ ++ +--- kicker/ui/kickoff_bar.h (Revision 0) ++++ kicker/ui/kickoff_bar.h (Revision 849791) +@@ -0,0 +1,53 @@ ++/***************************************************************** ++ ++ Copyright (c) 1996-2000 the kicker authors. See file AUTHORS. ++ Copyright (c) 2006 Dirk Mueller ++ ++ 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 __kickoff_bar_h__ ++#define __kickoff_bar_h__ ++ ++#include ++ ++class KickoffTabBar : public QTabBar ++{ ++ Q_OBJECT ++public: ++ KickoffTabBar(QWidget* parent, const char* name); ++ ++ void deactivateTabs(bool b); ++ virtual QSize sizeHint() const; ++ ++protected: ++ virtual void paint(QPainter*, QTab*, bool) const; ++ virtual void paintLabel(QPainter* p, const QRect& br, QTab* t, bool has_focus) const; ++ virtual void layoutTabs(); ++ virtual void dragEnterEvent(QDragEnterEvent*); ++ virtual void dragMoveEvent(QDragMoveEvent*); ++ virtual void mousePressEvent ( QMouseEvent * ); ++ ++signals: ++ void tabClicked(QTab*); ++ ++private: ++ bool m_tabsActivated; ++}; ++ ++ ++#endif +--- kicker/ui/k_mnu_stub.cpp (Revision 0) ++++ kicker/ui/k_mnu_stub.cpp (Revision 849791) +@@ -0,0 +1,141 @@ ++/***************************************************************** ++ ++Copyright (c) 2006 Dirk Mueller ++ ++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 "k_mnu_stub.h" ++#include "k_new_mnu.h" ++#include "k_mnu.h" ++ ++void KMenuStub::removeClientMenu(int id) ++{ ++ if(m_type == t_KMenu) ++ return m_w.kmenu->removeClientMenu(id); ++ return m_w.panelkmenu->removeClientMenu(id); ++} ++ ++int KMenuStub::insertClientMenu(KickerClientMenu *p) ++{ ++ if(m_type == t_KMenu) ++ return m_w.kmenu->insertClientMenu(p); ++ return m_w.panelkmenu->insertClientMenu(p); ++} ++ ++void KMenuStub::adjustSize() ++{ ++ if(m_type == t_KMenu) ++ return m_w.kmenu->adjustSize(); ++ return m_w.panelkmenu->adjustSize(); ++} ++ ++void KMenuStub::hide() ++{ ++ if(m_type == t_KMenu) ++ return m_w.kmenu->hide(); ++ return m_w.panelkmenu->hide(); ++} ++ ++void KMenuStub::show() ++{ ++ if(m_type == t_KMenu) ++ return m_w.kmenu->show(); ++ return m_w.panelkmenu->show(); ++} ++ ++void KMenuStub::showMenu() ++{ ++ if(m_type == t_KMenu) ++ return m_w.kmenu->showMenu(); ++ return m_w.panelkmenu->showMenu(); ++} ++ ++#if 0 ++void KMenuStub::resize() ++{ ++ if(m_type == t_KMenu) ++ return m_w.kmenu->resize(); ++ return m_w.panelkmenu->resize(); ++} ++#endif ++ ++void KMenuStub::popup(const QPoint &pos, int indexAtPoint) ++{ ++ return m_type == t_KMenu ? ++ m_w.kmenu->popup(pos, indexAtPoint) ++ : m_w.panelkmenu->popup(pos, indexAtPoint); ++} ++ ++void KMenuStub::selectFirstItem() ++{ ++ if(m_type == t_KMenu) ++ return m_w.kmenu->selectFirstItem(); ++ return m_w.panelkmenu->selectFirstItem(); ++} ++ ++void KMenuStub::resize(int w, int h) ++{ ++ if(m_type == t_KMenu) ++ return m_w.kmenu->resize(w, h); ++ return m_w.panelkmenu->resize(w, h); ++} ++ ++QSize KMenuStub::sizeHint() const ++{ ++ if(m_type == t_KMenu) ++ return m_w.kmenu->sizeHint(); ++ return m_w.panelkmenu->sizeHint(); ++} ++ ++bool KMenuStub::highlightMenuItem( const QString &menuId ) ++{ ++ if(m_type == t_KMenu) ++ return m_w.kmenu->highlightMenuItem(menuId); ++ return m_w.panelkmenu->highlightMenuItem(menuId); ++} ++ ++void KMenuStub::clearRecentMenuItems() ++{ ++ if(m_type == t_KMenu) ++ return m_w.kmenu->clearRecentAppsItems(); ++ return m_w.panelkmenu->clearRecentMenuItems(); ++} ++ ++void KMenuStub::initialize() ++{ ++ if(m_type == t_KMenu) ++ return m_w.kmenu->initialize(); ++ return m_w.panelkmenu->initialize(); ++} ++ ++bool KMenuStub::isVisible() const ++{ ++ if(m_type == t_KMenu) ++ return m_w.kmenu->isVisible(); ++ return m_w.panelkmenu->isVisible(); ++} ++ ++QWidget* KMenuStub::widget() ++{ ++ if(m_type == t_KMenu) ++ return m_w.kmenu; ++ return m_w.panelkmenu; ++} ++ +--- kicker/ui/kmenubase.ui.h (Revision 0) ++++ kicker/ui/kmenubase.ui.h (Revision 849791) +@@ -0,0 +1,9 @@ ++#include ++ ++void KMenuBase::init() ++{ ++ XSetWindowAttributes attrs; ++ attrs.override_redirect = True; ++ XChangeWindowAttributes( qt_xdisplay(), winId(), CWOverrideRedirect, &attrs ); ++ setWFlags( Qt::WType_Popup ); ++} +--- kicker/ui/mykickoffsearchinterface.h (Revision 0) ++++ kicker/ui/mykickoffsearchinterface.h (Revision 849791) +@@ -0,0 +1,47 @@ ++/*************************************************************************** ++ * Copyright (C) 2006 by Stephan Binner * ++ * * ++ * This program is free software; you can redistribute it and/or modify * ++ * it under the terms of the GNU General Public License as published by * ++ * the Free Software Foundation; either version 2 of the License, or * ++ * (at your option) any later version. * ++ * * ++ * This program is distributed in the hope that it will be useful, * ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of * ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * ++ * GNU General Public License for more details. * ++ * * ++ * You should have received a copy of the GNU General Public License * ++ * along with this program; if not, write to the * ++ * Free Software Foundation, Inc., * ++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ++ ***************************************************************************/ ++ ++#ifndef MYKICKOFFSEARCHINTERFACE_H ++#define MYKICKOFFSEARCHINTERFACE_H ++ ++#include "../interfaces/kickoffsearchinterface.h" ++ ++class KMenu; ++ ++using namespace KickoffSearch; ++ ++class MyKickoffSearchInterface :public KickoffSearchInterface ++{ ++ Q_OBJECT ++ ++public: ++ MyKickoffSearchInterface( KMenu*, QObject* parent, const char* name = 0 ); ++ ++ bool anotherHitMenuItemAllowed(int cat); ++ void addHitMenuItem(HitMenuItem* item); ++ void searchOver(); ++ void initCategoryTitlesUpdate(); ++ void updateCategoryTitles(); ++ ++private: ++ KMenu* _menu; ++ ++}; ++ ++#endif /* MYKICKOFFSEARCHINTERFACE_H */ +--- kicker/ui/itemview.h (Revision 0) ++++ kicker/ui/itemview.h (Revision 849791) +@@ -0,0 +1,260 @@ ++/***************************************************************** ++ ++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 __itemview_h__ ++#define __itemview_h__ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "kmenubase.h" ++#include "kmenuitembase.h" ++#include "service_mnu.h" ++ ++class KickerClientMenu; ++class KBookmarkMenu; ++class KActionCollection; ++class KBookmarkOwner; ++class Panel; ++class QWidgetStack; ++class KHistoryCombo; ++class QScrollView; ++class PopupMenuTitle; ++class QWidget; ++class QVBoxLayout; ++class QTimer; ++class KPixmap; ++ ++class KMenuItem : public QListViewItem ++{ ++public: ++ KMenuItem(int nId, QListView* parent) : QListViewItem(parent), m_id(nId) { init(); } ++ KMenuItem(int nId, QListViewItem* parent) : QListViewItem(parent), m_id(nId) { init(); } ++ ~KMenuItem(); ++ ++ void setIcon(const QString& icon, int size); ++ QString icon() const { return m_icon; } ++ void setTitle( const QString& text ); ++ QString title() const { return m_title; } ++ void setToolTip( const QString& text ); ++ QString toolTip() const { return m_tooltip; } ++ void setDescription(const QString& text); ++ QString description() const { return m_description; } ++ void setService(KService::Ptr& s) { m_s = s; } ++ KService::Ptr service() { return m_s; } ++ void setPath(const QString& u) { m_path = u; } ++ QString path() const { return m_path; } ++ void setMenuPath(const QString& u) { m_menuPath = u; } ++ QString menuPath() const { return m_menuPath; } ++ int id() const { return m_id; } ++ void setHasChildren(bool flag); ++ bool hasChildren() const { return m_has_children; } ++ void makeGradient(KPixmap &off, const QColor& c); ++ ++protected: ++ virtual void paintCell(QPainter* p, const QColorGroup & cg, int column, int width, int align); ++ virtual void paintCellInter(QPainter* p, const QColorGroup & cg, int column, int width, int align); ++ virtual void setup(); ++ ++private: ++ void init(); ++ ++ int m_id; ++ KService::Ptr m_s; ++ QString m_title; ++ QString m_description; ++ QString m_path; ++ QString m_icon; ++ QString m_tooltip; ++ QString m_menuPath; ++ float title_font_size; ++ float description_font_size; ++ bool m_has_children; ++ int m_old_width; ++ QPixmap right_triangle; ++}; ++ ++class KMenuItemSeparator : public KMenuItem ++{ ++public: ++ KMenuItemSeparator(int nId, QListView* parent); ++ virtual void setup(); ++ ++ virtual void paintCell(QPainter* p, const QColorGroup & cg, int column, int width, int align); ++ void setLink(const QString &text, const QString &link = QString::null ); ++ ++ QString linkUrl() const { return m_link_url; } ++ ++ /// returns true if the cursor has to change ++ bool hitsLink(const QPoint &pos); ++ ++protected: ++ void preparePixmap(int width); ++ QPixmap pixmap; ++ int left_margin; ++ ++private: ++ QListView* lv; ++ int cached_width; ++ QString m_link_text, m_link_url; ++ QRect m_link_rect; ++ ++}; ++ ++class KMenuItemHeader : public KMenuItemSeparator ++{ ++public: ++ KMenuItemHeader( int nId, const QString &relpath, QListView* parent); ++ virtual void setup(); ++ ++ virtual void paintCell(QPainter* p, const QColorGroup & cg, int column, int width, int align); ++ ++private: ++ QListView* lv; ++ QStringList paths; ++ QStringList texts; ++ QStringList icons; ++ QPixmap left_triangle; ++}; ++ ++class KMenuSpacer : public KMenuItem ++{ ++public: ++ KMenuSpacer(int nId, QListView* parent); ++ virtual void paintCell(QPainter* p, const QColorGroup & cg, int column, int width, int align); ++ virtual void setup(); ++ ++ void setHeight(int); ++}; ++ ++class ItemView : public KListView ++{ ++ friend class KMenuItem; ++ ++ Q_OBJECT ++public: ++ ItemView(QWidget* parent, const char* name = 0); ++ ++ KMenuItem* insertItem( const QString& icon, const QString& text, const QString& description, int nId, int nIndex, KMenuItem* parentItem = 0 ); ++ KMenuItem* insertItem( const QString& icon, const QString& text, const QString& description, const QString& path, int nId, int nIndex, KMenuItem* parentItem = 0 ); ++ int insertItem( PopupMenuTitle*, int, int); ++ int setItemEnabled(int id, bool enabled); ++ KMenuItemSeparator *insertSeparator(int id, const QString& text, int nIndex); ++ KMenuItemHeader *insertHeader(int id, const QString &relpath); ++ KMenuItem* insertMenuItem(KService::Ptr & s, int nId, int nIndex = -1, KMenuItem* parentItem = 0, ++ const QString &aliasname = QString::null, const QString &label = QString::null, ++ const QString &categoryIcon = QString::null); ++ KMenuItem* insertRecentlyItem(const QString& s, int nId, int nIndex = -1); ++ KMenuItem* insertDocumentItem(const QString& s, int nId, int nIndex = -1 , const QStringList* suppressGenericNames = 0, ++ const QString& aliasname = QString::null); ++ KMenuItem* insertSubItem(const QString& icon, const QString& caption, const QString& description, const QString& path, KMenuItem* parentItem); ++ KMenuItem* findItem(int nId); ++ ++ void setIconSize(int size) { m_iconSize = size; } ++ void setMouseMoveSelects(bool select) { m_mouseMoveSelects = select; } ++ void clear(); ++ int goodHeight(); ++ QString path; ++ void setBackPath( const QString &str ) { m_back_url = str; } ++ QString backPath() const { return m_back_url; } ++ ++public slots: ++ void slotItemClicked(QListViewItem*); ++ void slotMoveContent(); ++ ++signals: ++ void startService(KService::Ptr kservice); ++ void startURL(const QString& u); ++ ++protected: ++ void contentsMouseMoveEvent(QMouseEvent *e); ++ void contentsMousePressEvent ( QMouseEvent * e ); ++ void contentsWheelEvent(QWheelEvent *e); ++ void leaveEvent(QEvent *e); ++ virtual void resizeEvent ( QResizeEvent * e ); ++ virtual void viewportPaintEvent ( QPaintEvent * pe ); ++ virtual QDragObject* dragObject (); ++ virtual bool acceptDrag (QDropEvent* event) const; ++ virtual bool focusNextPrevChild(bool next); ++ ++private slots: ++ void slotItemClicked(int button, QListViewItem * item, const QPoint & pos, int c ); ++ ++private: ++ KMenuItem* itemAtIndex(int nIndex); ++ void moveItemToIndex(KMenuItem*, int); ++ ++ QWidget* m_itemBox; ++ QVBoxLayout* m_itemLayout; ++ KMenuItem *m_lastOne; ++ KMenuSpacer *m_spacer; ++ ++ QString m_back_url; ++ ++ bool m_mouseMoveSelects; ++ int m_iconSize; ++ int m_old_contentY; ++}; ++ ++class FavoritesItemView : public ItemView ++{ ++public: ++ FavoritesItemView(QWidget* parent, const char* name = 0); ++ ++protected: ++ virtual bool acceptDrag (QDropEvent* event) const; ++}; ++ ++class KMenuItemInfo ++{ ++public: ++ int m_id; ++ KService::Ptr m_s; ++ QString m_title; ++ QString m_description; ++ QString m_path; ++ QString m_icon; ++}; ++ ++class KMenuItemDrag : public QDragObject ++{ ++ public: ++ KMenuItemDrag(KMenuItem& item, QWidget *dragSource); ++ ~KMenuItemDrag(); ++ ++ virtual const char * format(int i = 0) const; ++ virtual QByteArray encodedData(const char *) const; ++ ++ static bool canDecode(const QMimeSource * e); ++ static bool decode(const QMimeSource* e, KMenuItemInfo& item); ++ ++ private: ++ QByteArray a; ++}; ++ ++#endif +--- kicker/ui/default-favs (Revision 0) ++++ kicker/ui/default-favs (Revision 849791) +@@ -0,0 +1,9 @@ ++MozillaFirefox.desktop ++kde-Kontact.desktop ++writer.desktop ++kde-amarok.desktop ++kde-digikam.desktop ++kde-Home.desktop ++kde-KControl.desktop ++kde-Help.desktop ++kde-konsole.desktop +--- kicker/ui/query.h (Revision 0) ++++ kicker/ui/query.h (Revision 849791) +@@ -0,0 +1,55 @@ ++/***************************************************************** ++ ++ Copyright (c) 2006 Stephan Binner ++ ++ 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 QUERY_H ++#define QUERY_H ++ ++#include ++#include ++ ++class Alternative ++{ ++public: ++ QStringList includes; ++ QStringList excludes; ++}; ++ ++class Query ++{ ++ public: ++ Query(); ++ void clear(); ++ void set(const QString &); ++ QString get() const; ++ bool matches(const QString &); ++ ++ private: ++ QString query_term; ++ QPtrList alternatives; ++ ++ void add_term(); ++ QString current_part; ++ Alternative *current_alternative; ++ bool within_quotes; ++ bool exclude_part; ++}; ++ ++#endif +--- kicker/ui/k_mnu_stub.h (Revision 0) ++++ kicker/ui/k_mnu_stub.h (Revision 849791) +@@ -0,0 +1,72 @@ ++/***************************************************************** ++ ++Copyright (c) 2006 Dirk Mueller ++ ++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_stub_h__ ++#define __k_mnu_stub_h__ ++ ++#include ++#include ++ ++class KickerClientMenu; ++class KMenu; ++class PanelKMenu; ++ ++ ++ ++ ++class KMenuStub ++{ ++public: ++ KMenuStub(KMenu* _kmenu) ++ : m_type(t_KMenu) { m_w.kmenu = _kmenu; } ++ KMenuStub(PanelKMenu* _panelkmenu) ++ : m_type(t_PanelKMenu) { m_w.panelkmenu = _panelkmenu; } ++ ~KMenuStub() {} ++ ++ void removeClientMenu(int id); ++ int insertClientMenu(KickerClientMenu *p); ++ void adjustSize(); ++ void hide(); ++ void show(); ++ void showMenu(); ++ void resize(); ++ void popup(const QPoint &pos, int indexAtPoint = -1); ++ void selectFirstItem(); ++ void resize(int, int); ++ QSize sizeHint() const; ++ bool highlightMenuItem( const QString &menuId ); ++ void clearRecentMenuItems(); ++ void initialize(); ++ ++ QWidget* widget(); ++ ++ bool isVisible() const; ++private: ++ enum {t_PanelKMenu, t_KMenu} m_type; ++ union { ++ KMenu* kmenu; ++ PanelKMenu* panelkmenu; ++ } m_w; ++}; ++ ++#endif +--- kicker/ui/Makefile.am (Revision 849788) ++++ kicker/ui/Makefile.am (Revision 849791) +@@ -1,38 +1,46 @@ + INCLUDES = -I$(srcdir)/../core -I../core -I$(srcdir)/../buttons \ + -I../../libkicker -I$(srcdir)/../../libkicker \ +- -I$(top_srcdir)/libkonq -I$(top_srcdir)/kdmlib $(all_includes) ++ -I$(top_srcdir)/libkonq -I$(top_srcdir)/kdmlib $(DBUS_INCS) $(all_includes) + + noinst_LTLIBRARIES = libkicker_ui.la + ++libkicker_ui_la_COMPILE_FIRST = kmenubase.h ++ + 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 \ ++ nonKDEButtonSettings.ui exe_dlg.cpp k_new_mnu.cpp k_mnu.cpp k_mnu.skel\ ++ quickbrowser_mnu.cpp service_mnu.cpp kmenubase.ui kmenuitembase.ui \ ++ addextension_mnu.cpp extensionop_mnu.cpp k_mnu_stub.cpp \ ++ recentapps.cpp browser_dlg.cpp itemview.cpp kickoff_bar.cpp \ + removeapplet_mnu.cpp removeextension_mnu.cpp removecontainer_mnu.cpp \ + removebutton_mnu.cpp popupmenutitle.cpp hidebutton.cpp \ +- addappletvisualfeedback.cpp ++ addappletvisualfeedback.cpp flipscrollview.cpp \ ++ media_watcher.cpp media_watcher.skel mykickoffsearchinterface.cpp query.cpp + +-libkicker_ui_la_LIBADD = $(top_builddir)/libkonq/libkonq.la $(top_builddir)/kdmlib/libdmctl.la ++libkicker_ui_la_LIBADD = $(top_builddir)/libkonq/libkonq.la $(top_builddir)/kdmlib/libdmctl.la \ ++ $(LIB_KABC) ../interfaces/libkickoffsearch_interfaces.la -llazy + + 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 \ ++ browser_mnu.h client_mnu.h dirdrop_mnu.h exe_dlg.h k_new_mnu.h k_mnu.h \ + quickbrowser_mnu.h service_mnu.h \ + addextension_mnu.h extensionop_mnu.h \ +- recentapps.h browser_dlg.h \ ++ recentapps.h browser_dlg.h itemview.h query.h \ + removeapplet_mnu.h removeextension_mnu.h removecontainer_mnu.h \ + removebutton_mnu.h popupmenutitle.h hidebutton.h addappletvisualfeedback.h + ++kicker_ui_data_DATA = default-favs ++kicker_ui_datadir = $(kde_datadir)/kicker ++ + 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 ++k_new_mnu.lo: ../../libkicker/kickerSettings.h + removecontainer_mnu.lo: ../core/extensionSettings.h + removeextension_mnu.lo: ../core/extensionSettings.h + service_mnu.lo: ../../libkicker/kickerSettings.h +--- kicker/ui/mykickoffsearchinterface.cpp (Revision 0) ++++ kicker/ui/mykickoffsearchinterface.cpp (Revision 849791) +@@ -0,0 +1,54 @@ ++/*************************************************************************** ++ * Copyright (C) 2006 by Stephan Binner * ++ * * ++ * This program is free software; you can redistribute it and/or modify * ++ * it under the terms of the GNU General Public License as published by * ++ * the Free Software Foundation; either version 2 of the License, or * ++ * (at your option) any later version. * ++ * * ++ * This program is distributed in the hope that it will be useful, * ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of * ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * ++ * GNU General Public License for more details. * ++ * * ++ * You should have received a copy of the GNU General Public License * ++ * along with this program; if not, write to the * ++ * Free Software Foundation, Inc., * ++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ++ ***************************************************************************/ ++ ++#include "mykickoffsearchinterface.h" ++#include "../ui/k_new_mnu.h" ++ ++MyKickoffSearchInterface::MyKickoffSearchInterface( KMenu* menu, QObject* parent, const char* name ) ++ : KickoffSearchInterface( parent, name ), _menu( menu ) ++{ ++} ++ ++bool MyKickoffSearchInterface::anotherHitMenuItemAllowed(int cat) ++{ ++ return _menu->anotherHitMenuItemAllowed(cat); ++} ++ ++void MyKickoffSearchInterface::addHitMenuItem(HitMenuItem* item) ++{ ++ _menu->addHitMenuItem(item); ++} ++ ++ ++void MyKickoffSearchInterface::searchOver() ++{ ++ _menu->searchOver(); ++} ++ ++void MyKickoffSearchInterface::initCategoryTitlesUpdate() ++{ ++ _menu->initCategoryTitlesUpdate(); ++} ++ ++void MyKickoffSearchInterface::updateCategoryTitles() ++{ ++ _menu->updateCategoryTitles(); ++} ++ ++#include "mykickoffsearchinterface.moc" +--- kicker/ui/itemview.cpp (Revision 0) ++++ kicker/ui/itemview.cpp (Revision 849791) +@@ -0,0 +1,1257 @@ ++/***************************************************************** ++ ++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 ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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_new_mnu.h" ++#include "itemview.h" ++ ++// -------------------------------------------------------------------------- ++ ++KMenuItem::~KMenuItem() ++{ ++ ItemView *listview = dynamic_cast( listView() ); ++ if ( listview && listview->m_lastOne == this) { ++ listview->m_lastOne = 0; ++ listview->m_old_contentY = -1; ++ } ++} ++ ++static double pointSize( double pixelSize, QPaintDevice *w ) ++{ ++ return pixelSize * 72. / QPaintDevice::x11AppDpiY( w->x11Screen () ); ++} ++ ++static int pixelSize( double pixelSize, QPaintDevice *w ) ++{ ++ return qRound( pixelSize * QPaintDevice::x11AppDpiY( w->x11Screen () ) / 72. ); ++} ++ ++void KMenuItem::init() ++{ ++ setMultiLinesEnabled(true); ++ m_s = 0; ++ m_path = QString::null; ++ m_icon = QString::null; ++ m_menuPath = QString::null; ++ setDragEnabled(true); ++ m_has_children = false; ++ m_old_width = -1; ++ if ( QApplication::reverseLayout() ) ++ right_triangle.load( locate( "data", "kicker/pics/left_triangle.png" ) ); ++ else ++ right_triangle.load( locate( "data", "kicker/pics/right_triangle.png" ) ); ++} ++ ++void KMenuItem::setTitle(const QString& txt) ++{ ++ m_title = txt; ++ setText( 0, txt ); ++ setup(); ++} ++ ++void KMenuItem::setToolTip(const QString& txt) ++{ ++ m_tooltip = txt; ++} ++ ++void KMenuItem::setDescription(const QString& txt) ++{ ++ m_description = txt; ++ setup(); ++} ++ ++void KMenuItem::setIcon(const QString& icon, int size) ++{ ++ m_icon = icon; ++ QListViewItem::setPixmap(0, KGlobal::iconLoader()->loadIcon(icon, KIcon::Panel, size )); ++} ++ ++void KMenuItem::setHasChildren( bool flag ) ++{ ++ m_has_children = flag; ++ repaint(); ++} ++ ++void KMenuItem::setup() ++{ ++ // if someone configured a larger generalFont than 10pt, he might have a _real_ problem with 7pt ++ // the 7pt could be read out of konquerorrc I guess ++ float min_font_size = 7. * QMAX(1., KGlobalSettings::generalFont().pointSizeFloat() / 10.); ++ ++ const int expected_height = 38; ++ description_font_size = QMAX( pointSize( expected_height * .3, listView() ) + KickerSettings::kickoffFontPointSizeOffset(), min_font_size ) ; ++ title_font_size = QMAX( pointSize( expected_height * .25, listView() ) + KickerSettings::kickoffFontPointSizeOffset(), min_font_size + 1 ); ++ ++ //kdDebug() << description_font_size << " " << title_font_size << " " << pointSize( expected_height * .25, listView() ) << endl; ++ QListViewItem::setup(); ++ setHeight( (int)QMAX( expected_height, pixelSize( title_font_size + description_font_size * 2.3, listView()))); ++} ++ ++void KMenuItem::paintCell(QPainter* p, const QColorGroup & cg, int column, int width, int align) ++{ ++ ItemView *listview = static_cast( listView() ); ++ int bottom = listView()->itemRect( this ).bottom(); ++ int diff = bottom - listView()->viewport()->height(); ++ ++ KPixmap pm; ++ pm.resize( width, height() ); ++ QPainter pp( &pm ); ++ paintCellInter( &pp, cg, column, width, align ); ++ pp.end(); ++ ++ if ( diff > 0 && diff <= height() ) // cut off ++ { ++ pm.resize( width, height() - diff ); ++ KPixmapEffect::blend( pm, float( diff ) / height(), ++ cg.color( QColorGroup::Background ), ++ KPixmapEffect::VerticalGradient ); ++ p->drawPixmap( 0, 0, pm ); ++ if ( listview->m_lastOne != this ) ++ { ++ listview->m_lastOne = this; ++ listview->m_old_contentY = -1; ++ } ++ } ++ else ++ { ++ p->drawPixmap( 0, 0, pm ); ++ if ( this == listview->m_lastOne ) { ++ if ( bottom < 0 ) ++ listview->m_lastOne = static_cast( itemAbove() ); ++ else ++ listview->m_lastOne = static_cast( itemBelow() ); ++ listview->m_old_contentY = -1; ++ repaint(); ++ } ++ } ++} ++ ++void KMenuItem::makeGradient( KPixmap &off, const QColor &c ) ++{ ++ KPixmap blend; ++ blend.resize( off.width() / 3, off.height() ); ++ bitBlt( &blend, 0, 0, &off, off.width() - blend.width(), 0, blend.width(), blend.height() ); ++ KPixmapEffect::blend( blend, 0.2, c, KPixmapEffect::HorizontalGradient ); ++ QPainter p( &off ); ++ p.drawPixmap( off.width() - blend.width(), 0, blend ); ++ p.end(); ++} ++ ++void KMenuItem::paintCellInter(QPainter* p, const QColorGroup & cg, int column, int width, int align) ++{ ++ const bool reverseLayout = QApplication::reverseLayout(); ++ ++ const BackgroundMode bgmode = listView()->viewport()->backgroundMode(); ++ const QColorGroup::ColorRole crole = QPalette::backgroundRoleFromMode( bgmode ); ++ QColor backg = cg.color( crole ); ++ ++ if ( isSelected() ) ++ backg = cg.color( QColorGroup::Highlight ); ++ p->fillRect( 0, 0, width, height(), backg ); ++ ++ QFontMetrics fm( p->fontMetrics() ); ++ ++ int pixsize = 32; ++ if ( height() < 36 ) ++ pixsize = 16; ++ const int left_margin = 30; ++ const int margin = 3; ++ ++// p->drawText( 2, 2, left_margin - 2, height(), align, QString::number( childCount () ) ); ++ ++ const QPixmap * pix = pixmap( column ); ++ ++ if ( pix ) ++ { ++ QPixmap pix32 = *pix; ++ ++ if ( pix->width() > pixsize ) ++ { ++ QImage i = pix->convertToImage().smoothScale( pixsize, pixsize ); ++ pix32.convertFromImage( i ); ++ } ++ if ( reverseLayout ) ++ p->drawPixmap( width - ( (pixsize - pix32.width()) / 2 + left_margin ) - pix32.width(), ++ ( height() - pix32.height() ) / 2, pix32 ); ++ else ++ p->drawPixmap( (pixsize - pix32.width()) / 2 + left_margin, ++ ( height() - pix32.height() ) / 2, pix32 ); ++ } ++ ++ if ( m_title.isEmpty() ) ++ return; ++ ++ int r = left_margin + pixsize + margin * 2; ++ ++ QFont f1 = p->font(); ++ f1.setPointSizeFloat( title_font_size ); ++ f1.setWeight( QFont::Normal ); // QFont::DemiBold == 63 ++ ++ QFont f2 = p->font(); ++ f2.setPointSizeFloat( description_font_size ); ++ f2.setWeight( QFont::Light ); ++ ++ int f1h = QFontMetrics( f1 ).height(); ++ int f2h = QFontMetrics( f2 ).height(); ++ ++ const int text_margin = 2; ++ int spacing = ( height() - f1h - f2h - text_margin ) / 2; ++ if ( m_description.isEmpty() ) ++ spacing = ( height() - f1h ) / 2; ++ ++ int right_triangle_size = pixelSize( 7, listView() ); ++ ++ int right_margin = listView()->verticalScrollBar()->width(); ++ if ( m_has_children ) ++ right_margin += right_triangle_size * 2; ++ ++ KPixmap off; ++ QPainter pp; ++ ++ off.resize( width-text_margin-r-right_margin, height() ); ++ pp.begin( &off ); ++ pp.fillRect( 0, 0, off.width(), off.height(), backg ); ++ ++ if (isSelected()) ++ pp.setPen( cg.color( QColorGroup::HighlightedText ) ); ++ else ++ pp.setPen( cg.color( QColorGroup::Text ) ); ++ ++ pp.setFont( f1 ); ++ pp.drawText( 0, 0, off.width(), off.height(), align, m_title ); ++ pp.end(); ++ if ( QFontMetrics( f1 ).width( m_title ) > off.width() ) ++ { ++ makeGradient( off, backg ); ++ if ( !m_description.isEmpty() ) ++ setToolTip( m_title + "

" + m_description ); ++ else ++ setToolTip( m_title ); ++ } ++ if ( reverseLayout ) ++ p->drawPixmap( width - off.width() - r, spacing, off ); ++ else ++ p->drawPixmap( r, spacing, off ); ++ ++ if ( !m_description.isEmpty() ) ++ { ++ pp.begin( &off ); ++ pp.fillRect( 0, 0, off.width(), off.height(), backg ); ++ ++ QColor myColor = cg.color( QColorGroup::Text ).light( 200 ); ++ if ( qGray( myColor.rgb() ) == 0 ) ++ myColor = QColor( 100, 100, 110 ); ++ pp.setPen( myColor ); ++ pp.setPen( isSelected() ? cg.color( QColorGroup::Mid ) : myColor ); ++ pp.setFont( f2 ); ++ pp.drawText( 0, 0, off.width(), off.height(), align, m_description ); ++ pp.end(); ++ if ( QFontMetrics( f2 ).width( m_description ) > off.width() ) ++ { ++ makeGradient( off, backg ); ++ setToolTip( m_title + "

" + m_description ); ++ } ++ if ( reverseLayout ) ++ p->drawPixmap( width - off.width() - r, spacing + text_margin + f1h, off ); ++ else ++ p->drawPixmap( r, spacing + text_margin + f1h, off ); ++ } ++ ++ if ( m_has_children ) ++ { ++ QImage i = right_triangle.convertToImage().smoothScale( right_triangle_size, ++ right_triangle_size ); ++ QPixmap tri; ++ tri.convertFromImage( i ); ++ ++ if ( reverseLayout ) ++ p->drawPixmap( right_margin - tri.width(), ( height() - f1h ) / 2, tri ); ++ else ++ p->drawPixmap( listView()->width() - right_margin, ( height() - f1h ) / 2, tri ); ++ } ++ ++ if ( m_old_width != width ) ++ { ++ // the listview caches paint events ++ m_old_width = width; ++ repaint(); ++ } ++} ++ ++// -------------------------------------------------------------------------- ++ ++KMenuItemSeparator::KMenuItemSeparator(int nId, QListView* parent) ++ : KMenuItem(nId, parent), lv(parent), cached_width( 0 ) ++{ ++ setEnabled(false); ++ left_margin = 15; ++} ++ ++void KMenuItemSeparator::setup() ++{ ++ KMenuItem::setup(); ++ ++ QFont f = QFont(); ++ QFontMetrics fm(f); ++ f.setPointSize( 8 + KickerSettings::kickoffFontPointSizeOffset() ); ++ if ( itemAbove() && !text( 0 ).isEmpty() ) ++ setHeight( (int)QMAX( 34., fm.height() * 1.4) ); ++ else ++ setHeight( (int)QMAX( 26., fm.height() * 1.4 ) ); ++} ++ ++void KMenuItemSeparator::setLink( const QString &text, const QString &url ) ++{ ++ m_link_text = text; ++ m_link_url = url; ++ m_link_rect = QRect(); ++} ++ ++bool KMenuItemSeparator::hitsLink( const QPoint &pos ) ++{ ++ return m_link_rect.contains( pos ); ++} ++ ++void KMenuItemSeparator::preparePixmap( int width ) ++{ ++ if ( cached_width != width ) ++ { ++ pixmap.load( locate("data", "kicker/pics/menu_separator.png" ) ); ++ QImage i = pixmap.convertToImage().smoothScale( width - 15 - left_margin, pixmap.height() ); ++ pixmap.convertFromImage( i ); ++ cached_width = width; ++ } ++} ++ ++void KMenuItemSeparator::paintCell(QPainter* p, const QColorGroup & cg, int column, int width, int align) ++{ ++ preparePixmap(width); ++ ++ const int h = height(); ++ ++ if (text(0).isEmpty()) { ++ KMenuItem::paintCell(p, cg, column, width, align); ++ p->drawPixmap( 15 , h/2, pixmap ); ++ } ++ else { ++ const BackgroundMode bgmode = lv->viewport()->backgroundMode(); ++ const QColorGroup::ColorRole crole = QPalette::backgroundRoleFromMode( bgmode ); ++ p->fillRect( 0, 0, width, h, cg.brush( crole ) ); ++ ++ int margin = 0; ++ if ( itemAbove() ) { ++ p->drawPixmap( 15 , h/4, pixmap ); ++ margin = h / 4; ++ } ++ QFont f = listView()->font(); ++ f.setWeight( QFont::Normal ); ++ f.setPointSize( 8 + KickerSettings::kickoffFontPointSizeOffset() ); ++ p->setFont( f ); ++ QColor myColor = cg.color( QColorGroup::Text ).light( 200 ); ++ if ( qGray( myColor.rgb() ) == 0 ) ++ myColor = QColor( 100, 100, 110 ); ++ p->setPen( myColor ); ++ int twidth = p->fontMetrics().width(text(0)); ++ int lwidth = 0; ++ int swidth = 0; ++ int fwidth = 0; ++ ++ if ( !m_link_text.isEmpty() ) ++ { ++ swidth = p->fontMetrics().width( " (" ); ++ lwidth = p->fontMetrics().width(m_link_text ); ++ fwidth = p->fontMetrics().width( ")" ); ++ } ++ int pos = int(lv->width() * 0.9 - twidth - swidth - lwidth - fwidth); ++ p->drawText( pos, margin + 5, ++ width, h - ( margin +5 ), AlignTop, text(0) ); ++ if ( !m_link_text.isEmpty() ) ++ { ++ pos += twidth; ++ p->drawText( pos, margin + 5, ++ width, h - ( margin +5 ), AlignTop, " (" ); ++ pos += swidth; ++ p->setPen( cg.color( QColorGroup::Link ) ); ++ f.setUnderline( true ); ++ p->setFont( f ); ++ p->drawText( pos, margin + 5, ++ width, h - ( margin +5 ), AlignTop, m_link_text ); ++ m_link_rect = QRect( pos, margin + 5, lwidth, p->fontMetrics().height() ); ++ pos += lwidth; ++ f.setUnderline( false ); ++ p->setFont( f ); ++ p->drawText( pos, margin + 5, ++ width, h - ( margin +5 ), AlignTop, ")" ); ++ } ++ } ++} ++ ++KMenuItemHeader::KMenuItemHeader(int nId, const QString& relPath, QListView* parent) ++ : KMenuItemSeparator(nId, parent) ++{ ++ setEnabled( false ); ++ QString path; ++ if (relPath.startsWith( "new/" /*"kicker:/new/"*/ )) { ++ paths.append( "kicker:/goup/" ); ++ texts.append( i18n("New Applications") ); ++ icons.append( "clock" ); ++ } ++ else if (relPath == "kicker:/restart/") { ++ texts.append( i18n("Restart Computer") ); ++ } ++ else if (relPath == "kicker:/switchuser/") { ++ texts.append( i18n("Switch User") ); ++ } ++ else { ++ KServiceGroup::Ptr subMenuRoot = KServiceGroup::group(relPath); ++ QStringList items = QStringList::split( '/', relPath ); ++ for ( QStringList::ConstIterator it = items.begin(); it != items.end(); ++it ) ++ { ++ path += *it + "/"; ++ paths.append( "kicker:/goup/" + path ); ++ KServiceGroup::Ptr subMenuRoot = KServiceGroup::group(path); ++ QString groupCaption = subMenuRoot->caption(); ++ texts.append( groupCaption ); ++ icons.append( subMenuRoot->icon() ); ++ } ++ } ++ ++ setPath( "kicker:/goup/" + path ); // the last wins for now ++ left_margin = 10; ++} ++ ++void KMenuItemHeader::setup() ++{ ++ KMenuItem::setup(); ++ ++ QFontMetrics fm( listView()->font() ); ++ setHeight( QMAX( int( texts.count() * fm.height() + ( texts.count() + 1 ) * 2 + 10 ), height()) ); ++ // nada ++} ++ ++void KMenuItemHeader::paintCell(QPainter* p, const QColorGroup & cg, int , int width, int align ) ++{ ++ preparePixmap(width); ++ ++ const BackgroundMode bgmode = listView()->viewport()->backgroundMode(); ++ const QColorGroup::ColorRole crole = QPalette::backgroundRoleFromMode( bgmode ); ++ ++ QBrush br = cg.brush( crole ); ++ if ( isSelected() ) { ++ br = cg.brush( QColorGroup::Highlight ); ++ p->fillRect( 0, 0, width, height() - 3, br ); ++ } else { ++ p->fillRect( 0, 0, width, height(), br ); ++ } ++ ++ QFontMetrics fm( p->fontMetrics() ); ++ const int left_margin = 10; ++ ++ const int margin = 3; ++ ++ int r = left_margin + margin * 2; ++ ++ const int min_font_size = 7; ++ int title_font_pixelSize = qRound( pixelSize( QMAX( pointSize( 12, listView() ) + KickerSettings::kickoffFontPointSizeOffset(), min_font_size + 1 ), listView() ) ); ++ ++ QFont f1 = p->font(); ++ f1.setPixelSize( title_font_pixelSize ); ++ p->setFont( f1 ); ++ int f1h = QFontMetrics( f1 ).height(); ++ ++ p->setPen( cg.color( QColorGroup::Text ) ); ++ ++ const int text_margin = 2; ++ int spacing = ( height() - texts.count() * f1h - QMAX( texts.count() - 1, 0 ) * text_margin ) / 2; ++ ++ for ( uint i = 0; i < texts.count(); ++i ) ++ { ++ if (i==texts.count()-1) { ++ f1.setWeight( QFont::DemiBold ); ++ p->setFont( f1 ); ++ f1h = QFontMetrics( f1 ).height(); ++ } ++ ++ p->drawText( r, spacing, width-text_margin-r, height(), align, texts[i] ); ++ spacing += text_margin + f1h; ++ r += title_font_pixelSize; ++ } ++ ++ p->drawPixmap( left_margin , height() - 2, pixmap ); ++} ++ ++KMenuSpacer::KMenuSpacer(int nId, QListView* parent) ++ : KMenuItem(nId, parent) ++{ ++ setEnabled(false); ++} ++ ++void KMenuSpacer::setup() ++{ ++ // nada ++} ++ ++void KMenuSpacer::paintCell(QPainter* p, const QColorGroup & cg, int , int width, int ) ++{ ++ const BackgroundMode bgmode = listView()->viewport()->backgroundMode(); ++ const QColorGroup::ColorRole crole = QPalette::backgroundRoleFromMode( bgmode ); ++ QBrush br = cg.brush( crole ); ++ ++ p->fillRect( 0, 0, width, height(), br ); ++} ++ ++void KMenuSpacer::setHeight( int i ) ++{ ++ KMenuItem::setHeight( i ); ++} ++ ++class ItemViewTip : public QToolTip ++{ ++public: ++ ItemViewTip( QWidget *parent, QListView *lv ); ++ ++ void maybeTip( const QPoint &pos ); ++ ++private: ++ QListView *view; ++ ++}; ++ ++ItemViewTip::ItemViewTip( QWidget *parent, QListView *lv ) ++ : QToolTip( parent ), view( lv ) ++{ ++} ++ ++void ItemViewTip::maybeTip( const QPoint &pos ) ++{ ++ KMenuItem *item = dynamic_cast( view->itemAt( pos ) ); ++ QPoint contentsPos = view->viewportToContents( pos ); ++ if ( !item ) ++ return; ++ ++ if ( item->toolTip().isNull() ) ++ return; ++ ++ QRect r = view->itemRect( item ); ++ int headerPos = view->header()->sectionPos( 0 ); ++ r.setLeft( headerPos ); ++ r.setRight( headerPos + view->header()->sectionSize( 0 ) ); ++ tip( r, item->toolTip() ); ++} ++ ++// -------------------------------------------------------------------------- ++ ++ItemView::ItemView(QWidget* parent, const char* name) ++ : KListView(parent, name), m_spacer( 0 ), ++ m_mouseMoveSelects(true), m_iconSize(32) ++{ ++ setHScrollBarMode( QScrollView::AlwaysOff ); ++ setFrameStyle( QFrame::NoFrame ); ++ setSelectionMode(QListView::Single); ++ addColumn(""); ++ header()->setStretchEnabled(1, 0); ++ //setColumnWidthMode(0, QListView::Maximum); ++ header()->hide(); ++ setMouseTracking(true); ++ setItemMargin(0); ++ setSorting(-1); ++ setTreeStepSize(38); ++ setFocusPolicy(QWidget::NoFocus); ++ ++ m_lastOne = 0; ++ m_old_contentY = -1; ++ ++ connect(this, SIGNAL(mouseButtonClicked( int, QListViewItem*, const QPoint &, int )), ++ SLOT(slotItemClicked(int, QListViewItem*, const QPoint &, int))); ++ ++ connect(this, SIGNAL(returnPressed(QListViewItem*)), SLOT(slotItemClicked(QListViewItem*))); ++ connect(this, SIGNAL(spacePressed(QListViewItem*)), SLOT(slotItemClicked(QListViewItem*))); ++ ++ new ItemViewTip( viewport(), this ); ++} ++ ++KMenuItemHeader *ItemView::insertHeader(int id, const QString &relpath) ++{ ++ KMenuItemHeader *newItem = new KMenuItemHeader(id, relpath, this ); ++ moveItemToIndex(newItem, 1); ++ setBackPath( "kicker:/goup/" + relpath ); // the last wins for now ++ ++ return newItem; ++} ++ ++KMenuItem* ItemView::findItem(int nId) ++{ ++ for (QListViewItemIterator it(this); it.current(); ++it) ++ { ++ if(static_cast(it.current())->id() == nId) ++ return static_cast(it.current()); ++ } ++ ++ return 0L; ++} ++ ++bool ItemView::focusNextPrevChild(bool /*next*/) ++{ ++ return false; ++} ++ ++KMenuItem* ItemView::itemAtIndex(int nIndex) ++{ ++ if(nIndex <= 0) ++ return 0L; ++ ++ if(nIndex >= childCount()) ++ return static_cast(lastItem()); ++ ++ int i = 1; ++ QListViewItemIterator it(this); ++ for (;it.current(); ++i, ++it) { ++ if(i == nIndex) ++ return static_cast(it.current()); ++ } ++ ++ return static_cast(lastItem()); ++} ++ ++KMenuItem* ItemView::insertItem( const QString& icon, const QString& text, const QString& description, const ++ QString& path, int nId, int nIndex, KMenuItem *parent) ++{ ++ KMenuItem* newItem = findItem(nId); ++ ++ if(!newItem && parent) ++ newItem = new KMenuItem(nId, parent ); ++ else if ( !newItem ) ++ newItem = new KMenuItem(nId, this ); ++ ++ newItem->setIcon(icon, m_iconSize); ++ newItem->setTitle(text); ++ newItem->setDescription(description); ++ newItem->setPath(path); ++ ++ if (nIndex==-1) ++ nIndex=childCount(); ++ ++ moveItemToIndex(newItem, nIndex); ++ ++ return newItem; ++} ++ ++KMenuItem* ItemView::insertItem( const QString& icon, const QString& text, const QString& description, ++ int nId, int nIndex, KMenuItem *parent) ++{ ++ return insertItem( icon, text, description, QString::null, nId, nIndex, parent); ++} ++ ++int ItemView::setItemEnabled(int id, bool enabled) ++{ ++ KMenuItem* item = findItem(id); ++ ++ if(item) ++ item->setEnabled(enabled); ++ ++ return 0; ++} ++ ++KMenuItemSeparator *ItemView::insertSeparator(int nId, const QString& text, int nIndex) ++{ ++ KMenuItemSeparator *newItem = new KMenuItemSeparator(nId, this); ++ ++ newItem->setText(0, text); ++ ++ if (nIndex==-1) ++ nIndex=childCount(); ++ ++ moveItemToIndex(newItem, nIndex); ++ return newItem; ++} ++ ++void ItemView::moveItemToIndex(KMenuItem* item, int nIndex) ++{ ++ ++ if (nIndex <= 0) { ++ takeItem(item); ++ KListView::insertItem(item); ++ } ++ else { ++ item->moveItem(itemAtIndex(nIndex)); ++ } ++} ++ ++void ItemView::slotMoveContent() ++{ ++ if ( !m_spacer ) ++ return; ++ ++ int item_height = 0; ++ QListViewItemIterator it( this ); ++ while ( it.current() ) { ++ if ( !dynamic_cast( it.current() ) && !it.current()->parent() && it.current()->isVisible() ) { ++ it.current()->invalidateHeight(); ++ item_height += it.current()->totalHeight(); ++ } ++ ++it; ++ } ++ ++ if ( height() > item_height ) ++ m_spacer->setHeight( height() - item_height ); ++ else ++ m_spacer->setHeight( 0 ); ++} ++ ++KMenuItem *ItemView::insertMenuItem(KService::Ptr& s, int nId, int nIndex, KMenuItem* parentItem, ++ const QString& aliasname, const QString & label, const QString & categoryIcon ) ++{ ++ if (!s) ++ return 0; ++ ++ QString serviceName = aliasname.isEmpty() ? s->name() : aliasname; ++ ++ kdDebug() << "insertMenuItem " << nId << " " << nIndex << " " << s->name() << endl; ++ KMenuItem* newItem = 0; //findItem(nId); ++ if(!newItem) ++ newItem = parentItem ? new KMenuItem(nId, parentItem) : new KMenuItem(nId, this); ++ ++ newItem->setIcon(s->icon()=="unknown" ? categoryIcon : s->icon(), m_iconSize); ++ if ((KickerSettings::DescriptionAndName || KickerSettings::menuEntryFormat() ++ == KickerSettings::DescriptionOnly) && !s->genericName().isEmpty()) { ++ newItem->setTitle(s->genericName()); ++ newItem->setDescription(label.isEmpty() ? serviceName : label); ++ } ++ else { ++ newItem->setTitle(label.isEmpty() ? serviceName : label); ++ newItem->setDescription(s->genericName()); ++ } ++ newItem->setService(s); ++ ++ if (nIndex==-2) ++ return newItem; ++ ++ if (nIndex==-1) ++ nIndex=childCount(); ++ ++ moveItemToIndex(newItem, nIndex); ++ ++ return newItem; ++} ++ ++KMenuItem* ItemView::insertDocumentItem(const QString& s, int nId, int nIndex, const QStringList* /*suppressGenericNames*/, ++ const QString& /*aliasname*/) ++{ ++ KMenuItem* newItem = findItem(nId); ++ ++ if(!newItem) ++ newItem = new KMenuItem(nId, this); ++ ++ KMimeType::Ptr mt = KMimeType::findByURL( s ); ++ newItem->setIcon(KMimeType::iconForURL( s ), m_iconSize); ++ newItem->setTitle(s); ++ newItem->setDescription(mt->comment()); ++ newItem->setPath(s); ++ ++ if (nIndex==-1) ++ nIndex=childCount(); ++ ++ moveItemToIndex(newItem, nIndex); ++ ++ return newItem; ++} ++ ++KMenuItem* ItemView::insertRecentlyItem(const QString& s, int nId, int nIndex) ++{ ++ KDesktopFile f(s, true /* read only */); ++ ++ KMenuItem* newItem = findItem(nId); ++ ++ if(!newItem) ++ newItem = new KMenuItem(nId, this); ++ ++ newItem->setIcon(f.readIcon(), m_iconSize); ++ ++ // work around upstream fixed bug ++ QString name=f.readName(); ++ if (name.isEmpty()) ++ name=f.readURL(); ++ ++ newItem->setTitle(name); ++ ++ QString comment = f.readComment(); ++ if (comment.isEmpty()) { ++ KURL url(f.readURL()); ++ if (!url.host().isEmpty()) ++ comment = i18n("Host: %1").arg(url.host()); ++ } ++ ++ newItem->setDescription(comment); ++ newItem->setPath(s); ++ ++ if (nIndex==-1) ++ nIndex=childCount(); ++ ++ moveItemToIndex(newItem, nIndex); ++ ++ return newItem; ++} ++ ++int ItemView::insertItem(PopupMenuTitle*, int, int) ++{ ++ return 0; ++} ++ ++KMenuItem* ItemView::insertSubItem(const QString& icon, const QString& caption, const QString& description, const QString& path, KMenuItem* parentItem) ++{ ++#warning FIXME ++ KMenuItem* newItem = parentItem ? new KMenuItem(-1, parentItem) : new KMenuItem(-1, this); ++ newItem->setTitle(caption); ++ newItem->setDescription(description); ++ newItem->setIcon(icon, m_iconSize); ++ newItem->setPath(path); ++ ++ return newItem; ++} ++ ++ ++ ++void ItemView::slotItemClicked(int button, QListViewItem * item, const QPoint & /*pos*/, int /*c*/ ) ++{ ++ if (button==1) ++ slotItemClicked(item); ++} ++ ++void ItemView::slotItemClicked(QListViewItem* item) ++{ ++ KMenuItem* kitem = dynamic_cast(item); ++ if ( !kitem ) ++ return; ++ ++ if(kitem->service()) { ++ emit startService(kitem->service()); ++ } ++ else if(!kitem->path().isEmpty()) { ++ emit startURL(kitem->path()); ++ } ++} ++ ++void ItemView::contentsMousePressEvent ( QMouseEvent * e ) ++{ ++ KListView::contentsMousePressEvent( e ); ++ ++ QPoint vp = contentsToViewport(e->pos()); ++ KMenuItemSeparator *si = dynamic_cast( itemAt( vp ) ); ++ if ( si ) ++ { ++ if ( si->hitsLink( vp - itemRect(si).topLeft() ) ) ++ emit startURL( si->linkUrl() ); ++ } ++} ++ ++void ItemView::contentsMouseMoveEvent(QMouseEvent *e) ++{ ++ QPoint vp = contentsToViewport(e->pos()); ++ QListViewItem * i = itemAt( vp ); ++ ++ bool link_cursor = false; ++ KMenuItemSeparator *si = dynamic_cast( i ); ++ if ( si ) ++ link_cursor = si->hitsLink( vp - itemRect(si).topLeft() ); ++ ++ if (i && !i->isSelectable() && !link_cursor) { ++ unsetCursor(); ++ viewport()->unsetCursor(); ++ return; ++ } ++ ++ KListView::contentsMouseMoveEvent(e); ++ ++ if (m_mouseMoveSelects) { ++ if(i && i->isEnabled() && !i->isSelected() && ++ // FIXME: This is wrong if you drag over the items. ++ (e->state() & (LeftButton|MidButton|RightButton)) == 0) ++ KListView::setSelected(i, true); ++ else if (!i && selectedItem()) ++ KListView::setSelected(selectedItem(), false); ++ } ++ ++ if ( link_cursor ) ++ setCursor( Qt::PointingHandCursor ); ++ else ++ unsetCursor(); ++ ++} ++ ++void ItemView::leaveEvent(QEvent* e) ++{ ++ KListView::leaveEvent(e); ++ ++ clearSelection(); ++} ++ ++void ItemView::resizeEvent ( QResizeEvent * e ) ++{ ++ KListView::resizeEvent( e ); ++// if ( m_lastOne ) ++// int diff = itemRect( m_lastOne ).bottom() - viewport()->height(); ++} ++ ++void ItemView::viewportPaintEvent ( QPaintEvent * pe ) ++{ ++ //kdDebug() << "viewportPaintEvent " << pe->rect() << " " << contentsY () << " " << m_old_contentY << endl; ++ KListView::viewportPaintEvent( pe ); ++ ++ if ( m_lastOne && m_old_contentY != contentsY() ) { ++ m_old_contentY = contentsY(); ++ m_lastOne->repaint(); ++ } ++} ++ ++void ItemView::clear() ++{ ++ KListView::clear(); ++ m_lastOne = 0; ++ m_old_contentY = -1; ++ m_back_url = QString::null; ++} ++ ++void ItemView::contentsWheelEvent(QWheelEvent *e) ++{ ++ KListView::contentsWheelEvent(e); ++ ++ QPoint vp = contentsToViewport(e->pos()); ++ QListViewItem * i = itemAt( vp ); ++ ++ if(i && i->isEnabled() && !i->isSelected() && ++ // FIXME: This is wrong if you drag over the items. ++ (e->state() & (LeftButton|MidButton|RightButton)) == 0) ++ KListView::setSelected(i, true); ++ else if (!i && selectedItem()) ++ KListView::setSelected(selectedItem(), false); ++} ++ ++QDragObject * ItemView::dragObject() ++{ ++ KMultipleDrag* o = 0; ++ QListViewItem *item = itemAt( viewport()->mapFromGlobal(QCursor::pos()) ); ++ if ( item ) { ++ KMenuItem* kitem = static_cast(item); ++ ++ if (dynamic_cast(item)) ++ return 0; ++ ++ o = new KMultipleDrag(viewport()); ++ QPixmap pix = KGlobal::iconLoader()->loadIcon( kitem->icon(), KIcon::Panel, m_iconSize); ++ QPixmap add = KGlobal::iconLoader()->loadIcon( "add", KIcon::Small ); ++ ++ QPainter p( &pix ); ++ p.drawPixmap(pix.height()-add.height(), pix.width()-add.width(), add); ++ p.end(); ++ ++ QBitmap mask; ++ ++ if (pix.mask()) ++ mask = *pix.mask(); ++ else { ++ mask.resize(pix.size()); ++ mask.fill(Qt::color1); ++ } ++ ++ bitBlt( &mask, pix.width()-add.width(), pix.height()-add.height(), add.mask(), 0, 0, add.width(), add.height(), OrROP ); ++ pix.setMask( mask ); ++ o->setPixmap(pix); ++ ++ if(kitem->service()) { ++ // If the path to the desktop file is relative, try to get the full ++ // path from KStdDirs. ++ QString path = kitem->service()->desktopEntryPath(); ++ path = locate("apps", path); ++ o->addDragObject(new KURLDrag(KURL::List(KURL(path)), 0)); ++ } ++ else if (kitem->path().startsWith("kicker:/new") || kitem->path().startsWith("system:/") ++ || kitem->path().startsWith("kicker:/switchuser_") || kitem->path().startsWith("kicker:/restart_")) { ++ delete o; ++ return 0; ++ } ++ else if (kitem->hasChildren()) { ++ o->addDragObject(new KURLDrag(KURL::List(KURL("programs:/"+kitem->menuPath())), 0)); ++ return o; ++ } ++ else if(!kitem->path().isEmpty() && !kitem->path().startsWith("kicker:/") && !kitem->path().startsWith("kaddressbook:/")) { ++ QString uri = kitem->path(); ++ ++ if (uri.startsWith(locateLocal("data", QString::fromLatin1("RecentDocuments/")))) { ++ KDesktopFile df(uri,true); ++ uri=df.readURL(); ++ } ++ ++ o->addDragObject(new KURLDrag(KURL::List(KURL(uri)), 0)); ++ } ++ ++ o->addDragObject(new KMenuItemDrag(*kitem,this)); ++ } ++ return o; ++} ++ ++int ItemView::goodHeight() ++{ ++ int item_height = 0; ++ QListViewItemIterator it( this ); ++ while ( it.current() ) { ++ if ( !dynamic_cast( it.current() ) && !it.current()->parent() && it.current()->isVisible() ) { ++ item_height += it.current()->height(); ++ } ++ ++it; ++ } ++ ++ return item_height; ++} ++ ++ ++KMenuItemDrag::KMenuItemDrag(KMenuItem& item, QWidget *dragSource) ++ : QDragObject(dragSource, 0) ++{ ++ QBuffer buff(a); ++ buff.open(IO_WriteOnly); ++ QDataStream s(&buff); ++ ++ s << item.id() << (item.service() ? item.service()->storageId() : QString::null) ++ << item.title() << item.description() << item.icon() << item.path(); ++} ++ ++KMenuItemDrag::~KMenuItemDrag() ++{ ++} ++ ++const char * KMenuItemDrag::format(int i) const ++{ ++ if (i == 0) ++ return "application/kmenuitem"; ++ ++ return 0; ++} ++ ++QByteArray KMenuItemDrag::encodedData(const char* mimeType) const ++{ ++ if (QString("application/kmenuitem") == mimeType) ++ return a; ++ ++ return QByteArray(); ++} ++ ++bool KMenuItemDrag::canDecode(const QMimeSource * e) ++{ ++ if (e->provides( "application/kmenuitem" ) ) ++ return true; ++ ++ return false; ++} ++ ++bool ItemView::acceptDrag (QDropEvent* event) const ++{ ++ if ( !acceptDrops() ) ++ return false; ++ ++ if (KMenuItemDrag::canDecode(event)) ++ return true; ++ ++ if (QTextDrag::canDecode(event)) { ++ QString text; ++ QTextDrag::decode(event,text); ++ return !text.startsWith("programs:/"); ++ } ++ ++ return itemsMovable(); ++} ++ ++bool KMenuItemDrag::decode(const QMimeSource* e, KMenuItemInfo& item) ++{ ++ QByteArray a = e->encodedData("application/kmenuitem"); ++ ++ if (a.isEmpty()) { ++ QStringList l; ++ bool ret = QUriDrag::decodeToUnicodeUris( e, l ); ++ if ( ret ) ++ { ++ for ( QStringList::ConstIterator it = l.begin(); it != l.end(); ++it ) ++ { ++ QString url = *it; ++ kdDebug () << "Url " << url << endl; ++ item.m_path = KURL( url ).path(); ++ if ( KDesktopFile::isDesktopFile( item.m_path ) ) ++ { ++ KDesktopFile df( item.m_path, true ); ++ item.m_description = df.readGenericName(); ++ item.m_icon = df.readIcon(); ++ item.m_title = df.readName(); ++ } ++ else ++ { ++ item.m_title = item.m_path; ++ item.m_icon = KMimeType::iconForURL( url ); ++ item.m_title = item.m_path.section( '/', -1, -1 ); ++ int last_slash = url.findRev ('/', -1); ++ if (last_slash == 0) ++ item.m_description = i18n("Directory: /)"); ++ else ++ item.m_description = i18n("Directory: ") + url.section ('/', -2, -2); ++ } ++ ++ return true; ++ } ++ } ++ return false; ++ } ++ ++ QBuffer buff(a); ++ buff.open(IO_ReadOnly); ++ QDataStream s(&buff); ++ ++ KMenuItemInfo i; ++ QString storageId; ++ s >> i.m_id >> storageId >> i.m_title >> i.m_description >> i.m_icon >> i.m_path; ++ ++ i.m_s = storageId.isEmpty() ? 0 : KService::serviceByStorageId(storageId); ++ item = i; ++ ++ return true; ++} ++ ++FavoritesItemView::FavoritesItemView(QWidget* parent, const char* name) ++ : ItemView(parent, name) ++{ ++} ++ ++bool FavoritesItemView::acceptDrag (QDropEvent* event) const ++{ ++ if (event->source()==this->viewport()) ++ return true; ++ ++ if (KMenuItemDrag::canDecode(event)) { ++ KMenuItemInfo item; ++ KMenuItemDrag::decode(event,item); ++ QStringList favs = KickerSettings::favorites(); ++ ++ if (item.m_s) ++ return favs.find(item.m_s->storageId())==favs.end(); ++ else { ++ QStringList::Iterator it; ++ ++ QString uri = item.m_path; ++ ++ if (uri.startsWith(locateLocal("data", QString::fromLatin1("RecentDocuments/")))) { ++ KDesktopFile df(uri,true); ++ uri=df.readURL(); ++ } ++ ++ for (it = favs.begin(); it != favs.end(); ++it) { ++ if ((*it)[0]=='/') { ++ KDesktopFile df((*it),true); ++ if (df.readURL().replace("file://",QString::null)==uri) ++ break; ++ } ++ } ++ return it==favs.end(); ++ } ++ } ++ ++ if (QTextDrag::canDecode(event)) { ++ QString text; ++ QTextDrag::decode(event,text); ++ QStringList favs = KickerSettings::favorites(); ++ ++ if (text.endsWith(".desktop")) { ++ KService::Ptr p = KService::serviceByDesktopPath(text.replace("file://",QString::null)); ++ return (p && favs.find(p->storageId())==favs.end()); ++ } ++ else { ++ QStringList::Iterator it; ++ for (it = favs.begin(); it != favs.end(); ++it) { ++ if ((*it)[0]=='/') { ++ KDesktopFile df((*it),true); ++ if (df.readURL().replace("file://",QString::null)==text) ++ break; ++ } ++ } ++ return it==favs.end(); ++ } ++ } ++ ++ return itemsMovable(); ++} ++ ++#include "itemview.moc" ++ ++// vim:cindent:sw=4: +--- kicker/ui/media_watcher.cpp (Revision 0) ++++ kicker/ui/media_watcher.cpp (Revision 849791) +@@ -0,0 +1,57 @@ ++/***************************************************************** ++ ++Copyright (c) 2006 Stephan Kulow ++ ++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 "media_watcher.h" ++#include ++#include ++#include ++#include ++ ++MediaWatcher::MediaWatcher( QObject *parent ) : ++ QObject( parent ), DCOPObject("mediawatcher") ++{ ++ connectDCOPSignal( "kded", "mediamanager", "mediumAdded(QString,bool)", ++ "slotMediumAdded(QString,bool)", true ); ++ connectDCOPSignal( "kded", "mediamanager", "mediumRemoved(QString,bool)", ++ "slotMediumAdded(QString,bool)", true ); ++ connectDCOPSignal( "kded", "mediamanager", "mediumChanged(QString,bool)", ++ "slotMediumAdded(QString,bool)", true ); ++ ++ updateDevices(); ++} ++ ++void MediaWatcher::updateDevices() ++{ ++ DCOPRef nsd( "kded", "mediamanager" ); ++ nsd.setDCOPClient( kapp->dcopClient() ); ++ m_devices = nsd.call( "fullList" ); ++} ++ ++void MediaWatcher::slotMediumAdded( QString item, bool a ) ++{ ++ updateDevices(); ++ ++ emit mediumChanged(); ++} ++ ++#include "media_watcher.moc" + +Eigenschaftsänderungen: kicker/ui +___________________________________________________________________ +Geändert: svn:ignore + - nonKDEButtonSettings.h +appletitem.h +appletview.cpp +nonKDEButtonSettings.cpp +k_mnu.kidl +appletview.h +appletitem.cpp +k_mnu_skel.cpp +.deps +.libs +Makefile +Makefile.in +*.moc + + + nonKDEButtonSettings.h +appletitem.h +appletview.cpp +nonKDEButtonSettings.cpp +k_mnu.kidl +appletview.h +appletitem.cpp +k_mnu_skel.cpp +.deps +.libs +Makefile +Makefile.in +*.moc +kmenuitembase.cpp +media_watcher.kidl +kmenubase.cpp +kmenuitembase.h +kmenubase.h +media_watcher_skel.cpp + + +--- kicker/buttons/knewbutton.cpp (Revision 0) ++++ kicker/buttons/knewbutton.cpp (Revision 849791) +@@ -0,0 +1,455 @@ ++/***************************************************************** ++ ++Copyright (c) 2006 Stephan Binner ++ Stephan Kulow ++ Dirk Mueller ++ ++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 ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "kickerSettings.h" ++ ++#include "config.h" ++#include "global.h" ++ ++#include "menumanager.h" ++#include "k_mnu_stub.h" ++#include "k_new_mnu.h" ++ ++#include "knewbutton.h" ++#include "knewbutton.moc" ++ ++KNewButton *KNewButton::m_self = 0; ++ ++KNewButton::KNewButton( QWidget* parent ) ++ : KButton( parent ), ++ m_oldPos(0,0) ++{ ++ Q_ASSERT( !m_self ); ++ m_self = this; ++ m_hoverTimer = -1; ++ m_openTimer = -1; ++ m_active = false; ++ m_mouseInside = false; ++ m_drag = false; ++ ++ setIconAlignment((Qt::AlignmentFlags)(AlignTop|AlignRight)); ++ setAcceptDrops(true); ++ setIcon("kmenu-suse"); ++ setDrawArrow(false); ++ ++ m_movie = new QMovie(locate("data", "kicker/pics/kmenu_basic.mng")); ++ m_movie->connectUpdate(this, SLOT(updateMovie())); ++ m_movie->connectStatus(this, SLOT(slotStatus(int))); ++ m_movie->connectResize(this, SLOT(slotSetSize(const QSize&))); ++ ++ QApplication::desktop()->screen()->installEventFilter(this); ++ setMouseTracking(true); ++} ++ ++KNewButton::~KNewButton() ++{ ++ if ( m_self == this ) ++ m_self = 0; ++ setMouseTracking(false); ++ delete m_movie; ++} ++ ++void KNewButton::slotStatus(int status) ++{ ++ if(status == QMovie::EndOfLoop) ++ slotStopAnimation(); ++} ++ ++QColor KNewButton::borderColor() const ++{ ++ QImage img = m_active_pixmap.convertToImage(); ++ ++ for (int i = 0; i < img.width(); ++i) { ++ QRgb rgb = img.pixel(orientation() == Qt::Horizontal ? img.width() - i - 1 : ++ i, 2); ++ ++ if (qGreen(rgb) > 0x50) ++ return rgb; ++ } ++ ++ return img.pixel( orientation() == Qt::Horizontal ? img.width() - 2 : 2, 2); ++} ++ ++void KNewButton::show() ++{ ++ KButton::show(); ++ ++ if (KickerSettings::firstRun()) { ++ QTimer::singleShot(500,this,SLOT(slotExecMenu())); ++ KickerSettings::setFirstRun(false); ++ KickerSettings::writeConfig(); ++ } ++} ++ ++void KNewButton::updateMovie() ++{ ++ m_oldPos = QPoint( -1, -1 ); ++ drawEye(); ++ ++ if (!m_active && m_movie->running()) ++ m_movie->pause(); ++} ++ ++void KNewButton::setPopupDirection(KPanelApplet::Direction d) ++{ ++ KButton::setPopupDirection(d); ++ ++ delete m_movie; ++ ++ switch (d) { ++ case KPanelApplet::Left: ++ setIconAlignment((Qt::AlignmentFlags)(AlignTop|AlignLeft)); ++ m_movie = new QMovie(locate("data", "kicker/pics/kmenu_vertical.mng")); ++ break; ++ case KPanelApplet::Right: ++ setIconAlignment((Qt::AlignmentFlags)(AlignTop|AlignRight)); ++ m_movie = new QMovie(locate("data", "kicker/pics/kmenu_vertical.mng")); ++ break; ++ case KPanelApplet::Up: ++ setIconAlignment((Qt::AlignmentFlags)(AlignTop|AlignHCenter)); ++ m_movie = new QMovie(locate("data", "kicker/pics/kmenu_basic.mng")); ++ break; ++ case KPanelApplet::Down: ++ setIconAlignment((Qt::AlignmentFlags)(AlignBottom|AlignHCenter)); ++ m_movie = new QMovie(locate("data", "kicker/pics/kmenu_flipped.mng")); ++ } ++ ++ m_movie->connectUpdate(this, SLOT(updateMovie())); ++ m_movie->connectStatus(this, SLOT(slotStatus(int))); ++ m_movie->connectResize(this, SLOT(slotSetSize(const QSize&))); ++} ++ ++void KNewButton::slotSetSize(const QSize& s) ++{ ++ m_iconSize = s; ++} ++ ++double KNewButton::buttonScaleFactor(const QSize& s) const ++{ ++ double sf = 1.0; ++ ++ switch (popupDirection()) { ++ case KPanelApplet::Left: ++ case KPanelApplet::Right: ++// sf = kMin(double(s.width()) / m_iconSize.height(), double(s.height()) / m_iconSize.width()); ++// break; ++ case KPanelApplet::Up: ++ case KPanelApplet::Down: ++ sf = kMin(double(s.width()) / m_iconSize.width(), double(s.height()) / m_iconSize.height()); ++ break; ++ } ++ ++ if (sf > 0.8) sf = 1.0; ++ return sf; ++} ++ ++int KNewButton::widthForHeight(int height) const ++{ ++ int r = m_iconSize.width() * buttonScaleFactor(QSize(m_iconSize.width(), height)); ++ ++ if (!m_movie->running() && height != m_active_pixmap.height()) ++ { ++ KNewButton* that = const_cast(this); ++ QTimer::singleShot(0, that, SLOT(slotStopAnimation())); ++ } ++ ++ return r; ++} ++ ++int KNewButton::preferredDimension(int panelDim) const ++{ ++ return kMax(m_icon.width(), m_icon.height()); ++} ++ ++int KNewButton::heightForWidth(int width) const ++{ ++ int r = m_iconSize.width() * buttonScaleFactor(QSize(width, m_iconSize.height())); ++ if (!m_movie->running() && width != m_active_pixmap.width()) ++ { ++ KNewButton* that = const_cast(this); ++ QTimer::singleShot(0, that, SLOT(slotStopAnimation())); ++ } ++ return r; ++} ++ ++bool KNewButton::eventFilter(QObject *o, QEvent *e) ++{ ++ if (e->type() == QEvent::MouseButtonRelease || ++ e->type() == QEvent::MouseButtonPress || ++ e->type() == QEvent::MouseButtonDblClick ) ++ { ++ QMouseEvent *me = static_cast(e); ++ if (rect().contains(mapFromGlobal(me->globalPos()))) ++ { ++ if (m_pressedDuringPopup && m_popup && m_openTimer != -1 ++ && (me->button() & Qt::LeftButton) ) ++ return true; ++ } ++ } ++ ++ if (KickerSettings::kickoffDrawGeekoEye() && e->type() == QEvent::MouseMove) ++ { ++ QMouseEvent *me = static_cast(e); ++ if ((me->state() & MouseButtonMask) == NoButton) ++ drawEye(); ++ } ++ ++ return KButton::eventFilter(o, e); ++} ++ ++void KNewButton::drawEye() ++{ ++#define eye_x 62 ++#define eye_y 13 ++ QPoint mouse = QCursor::pos(); ++ QPoint me = mapToGlobal(QPoint(eye_x, eye_y)); ++ double a = atan2(mouse.y() - me.y(), mouse.x() - me.x()); ++ int dx = int(2.1 * cos(a)); ++ int dy = int(2.1 * sin(a)); ++ ++ QPoint newpos(eye_x+dx,eye_y+dy); ++ if (newpos!=m_oldPos) { ++ m_oldPos = newpos; ++ QPixmap pixmap = m_active_pixmap; ++ ++ double sf = 1.0; ++ ++ if(!m_movie->framePixmap().isNull()) ++ { ++ pixmap = m_movie->framePixmap(); ++ pixmap.detach(); ++ m_iconSize = pixmap.size(); ++ sf = buttonScaleFactor(size()); ++ ++ if (KickerSettings::kickoffDrawGeekoEye()) { ++ QPainter p(&pixmap); ++ p.setPen(white); ++ p.setBrush(white); ++ // p.setPen(QColor(110,185,55)); ++ p.drawRect(eye_x+dx, eye_y+dy, 2, 2); ++ p. end(); ++ } ++ } ++ ++ QWMatrix matrix; ++ switch (popupDirection()) { ++ case KPanelApplet::Left: ++ matrix.scale(sf, -sf); ++ matrix.rotate(90); ++ break; ++ case KPanelApplet::Up: ++ matrix.scale(sf, sf); ++ break; ++ case KPanelApplet::Right: ++ matrix.scale(sf, -sf); ++ matrix.rotate(90); ++ break; ++ case KPanelApplet::Down: ++ matrix.scale(sf, sf); ++ break; ++ } ++ m_active_pixmap = pixmap.xForm(matrix); ++ ++ repaint(false); ++ } ++#undef eye_x ++#undef eye_y ++} ++ ++void KNewButton::enterEvent(QEvent* e) ++{ ++ KButton::enterEvent(e); ++ ++ QSize s(size()); ++ s *= 0.25; ++ s = s.expandedTo(QSize(6,6)); ++ ++ switch (popupDirection()) { ++ case KPanelApplet::Left: ++ m_sloppyRegion = QRect(rect().topRight() - QPoint(s.width()-1, 0), s); ++ break; ++ case KPanelApplet::Right: ++ m_sloppyRegion = QRect(rect().topLeft(), s); ++ break; ++ case KPanelApplet::Up: ++ m_sloppyRegion = QRect(rect().bottomLeft() - QPoint(0, s.height()-1), s); ++ break; ++ case KPanelApplet::Down: ++ m_sloppyRegion = QRect(rect().topLeft(), s); ++ } ++ ++ m_active = true; ++ m_movie->unpause(); ++ m_movie->restart(); ++} ++ ++void KNewButton::rewindMovie() ++{ ++ m_oldPos = QPoint( -1, -1 ); ++ m_movie->unpause(); ++} ++ ++void KNewButton::dragEnterEvent(QDragEnterEvent* /*e*/) ++{ ++ if (m_hoverTimer != -1) ++ killTimer(m_hoverTimer); ++ ++ m_hoverTimer = startTimer(QApplication::startDragTime()); ++ m_mouseInside = true; ++ m_drag = true; ++} ++ ++void KNewButton::dragLeaveEvent(QDragLeaveEvent* /*e*/) ++{ ++ m_mouseInside = false; ++ m_drag = false; ++} ++ ++void KNewButton::leaveEvent(QEvent* e) ++{ ++ m_mouseInside = false; ++ if (m_hoverTimer != -1) ++ killTimer(m_hoverTimer); ++ m_hoverTimer = -1; ++ ++ KButton::leaveEvent(e); ++} ++ ++void KNewButton::mouseMoveEvent(QMouseEvent* e) ++{ ++ KButton::mouseMoveEvent(e); ++ ++ m_mouseInside = m_sloppyRegion.contains(e->pos()); ++ ++ if ( m_sloppyRegion.contains(e->pos())) ++ { ++ if (m_hoverTimer == -1 && KickerSettings::openOnHover()) ++ m_hoverTimer = startTimer(kMax(200,QApplication::doubleClickInterval()/2)); ++ } ++ else if (m_hoverTimer != -1) ++ { ++ killTimer(m_hoverTimer); ++ m_hoverTimer = -1; ++ } ++} ++ ++void KNewButton::slotStopAnimation() ++{ ++ m_active = false; ++ m_movie->pause(); ++ m_movie->restart(); ++ QTimer::singleShot(200, this, SLOT(rewindMovie())); ++} ++ ++const QPixmap& KNewButton::labelIcon() const ++{ ++ return m_active_pixmap; ++} ++ ++void KNewButton::slotExecMenu() ++{ ++ if (m_openTimer != -1) ++ killTimer(m_openTimer); ++ ++ m_openTimer = startTimer(QApplication::doubleClickInterval() * 3); ++ ++ if (m_active) ++ { ++ m_active = false; ++ m_movie->pause(); ++ m_movie->restart(); ++ } ++ ++ KButton::slotExecMenu(); ++ ++ assert(!KickerTip::tippingEnabled()); ++ assert(dynamic_cast(m_popup)); ++ ++ disconnect(dynamic_cast(m_popup), SIGNAL(aboutToHide()), this, ++ SLOT(slotStopAnimation())); ++ connect(dynamic_cast(m_popup), SIGNAL(aboutToHide()), ++ SLOT(slotStopAnimation())); ++ ++ m_popup->move(KickerLib::popupPosition(popupDirection(), m_popup, this)); ++ // I wish KMenu would properly done itself when it closes. But it doesn't. ++ ++ bool useEffect = true; // could be QApplication::isEffectEnabled() ++ useEffect = false; // too many Qt bugs to be useful ++ if (m_drag) ++ useEffect = false; ++ ++ m_drag = false; // once is enough ++ ++ if (useEffect) ++ { ++ switch (popupDirection()) { ++ case KPanelApplet::Left: ++ qScrollEffect(m_popup, QEffects::LeftScroll); ++ break; ++ case KPanelApplet::Up: ++ qScrollEffect(m_popup, QEffects::UpScroll); ++ break; ++ case KPanelApplet::Right: ++ qScrollEffect(m_popup, QEffects::RightScroll); ++ break; ++ case KPanelApplet::Down: ++ qScrollEffect(m_popup, QEffects::DownScroll); ++ break; ++ } ++ } ++ else ++ static_cast(m_popup)->show(); ++} ++ ++void KNewButton::timerEvent(QTimerEvent* e) ++{ ++ if (e->timerId() == m_hoverTimer) ++ { ++ if (m_mouseInside && !isDown()) ++ showMenu(); ++ ++ killTimer(m_hoverTimer); ++ m_hoverTimer = -1; ++ } ++ if (e->timerId() == m_openTimer) ++ { ++ killTimer(m_openTimer); ++ m_openTimer = -1; ++ } ++} +--- kicker/buttons/knewbutton.h (Revision 0) ++++ kicker/buttons/knewbutton.h (Revision 849791) +@@ -0,0 +1,98 @@ ++/***************************************************************** ++ ++Copyright (c) 2006 Stephan Binner ++ Stephan Kulow ++ Dirk Mueller ++ ++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 __knewbutton_h__ ++#define __knewbutton_h__ ++ ++#include "kbutton.h" ++ ++#include ++#include ++ ++/** ++ * Button that contains the PanelKMenu and client menu manager. ++ */ ++class KNewButton : public KButton ++{ ++ Q_OBJECT ++ ++public: ++ KNewButton( QWidget *parent ); ++ ~KNewButton(); ++ ++ static KNewButton *self() { return m_self; } ++ ++ void loadConfig( const KConfigGroup& config ); ++ ++ virtual const QPixmap& labelIcon() const; ++ ++ virtual int widthForHeight(int height) const; ++ virtual int preferredDimension(int panelDim) const; ++ virtual int heightForWidth(int width) const; ++ ++ QColor borderColor() const; ++ ++ virtual void setPopupDirection(KPanelApplet::Direction d); ++ ++private slots: ++ void slotStatus(int); ++ void slotSetSize(const QSize&); ++ void slotStopAnimation(); ++ void rewindMovie(); ++ void updateMovie(); ++ ++protected: ++ virtual void show(); ++ virtual void slotExecMenu(); ++ virtual QString tileName() { return "KMenu"; } ++ virtual QString defaultIcon() const { return "go"; } ++ ++ virtual void enterEvent(QEvent* e); ++ virtual void leaveEvent(QEvent* e); ++ virtual void mouseMoveEvent(QMouseEvent* e); ++ virtual void dragEnterEvent(QDragEnterEvent*); ++ virtual void dragLeaveEvent(QDragLeaveEvent*); ++ virtual bool eventFilter(QObject *, QEvent *); ++ void timerEvent(QTimerEvent*); ++ ++private: ++ void drawEye(); ++ double buttonScaleFactor(const QSize& s) const; ++ ++ QMovie* m_movie; ++ QPixmap m_active_pixmap; ++ QPoint m_oldPos; ++ QSize m_iconSize; ++ QRect m_sloppyRegion; ++ int m_hoverTimer; ++ int m_openTimer; ++ bool m_active; ++ bool m_mouseInside; ++ bool m_drag; ++ ++ static KNewButton *m_self; ++}; ++ ++#endif +--- kicker/buttons/browserbutton.cpp (Revision 849788) ++++ kicker/buttons/browserbutton.cpp (Revision 849791) +@@ -65,7 +65,7 @@ + topMenu = new PanelBrowserMenu( path ); + setPopup(topMenu); + +- _menuTimer = new QTimer( this ); ++ _menuTimer = new QTimer( this, "_menuTimer" ); + connect( _menuTimer, SIGNAL(timeout()), SLOT(slotDelayedPopup()) ); + + QToolTip::add(this, i18n("Browse: %1").arg(path)); +--- kicker/buttons/kbutton.cpp (Revision 849788) ++++ kicker/buttons/kbutton.cpp (Revision 849791) +@@ -33,6 +33,7 @@ + + #include "menumanager.h" + #include "k_mnu.h" ++#include "k_mnu_stub.h" + + #include "kbutton.h" + #include "kbutton.moc" +@@ -43,7 +44,7 @@ + QToolTip::add(this, i18n("Applications, tasks and desktop sessions")); + setTitle(i18n("K Menu")); + +- setPopup(MenuManager::the()->kmenu()); ++ setPopup(MenuManager::the()->kmenu()->widget()); + MenuManager::the()->registerKButton(this); + setIcon("kmenu"); + +--- kicker/buttons/Makefile.am (Revision 849788) ++++ kicker/buttons/Makefile.am (Revision 849791) +@@ -1,10 +1,10 @@ + INCLUDES = -I$(srcdir)/../core -I$(srcdir)/../../libkicker -I../../libkicker \ +- -I$(srcdir)/../ui -I$(top_srcdir)/libkonq $(all_includes) ++ -I../ui -I$(srcdir)/../ui -I$(top_srcdir)/libkonq $(all_includes) + + noinst_LTLIBRARIES = libkicker_buttons.la + + libkicker_buttons_la_SOURCES = servicebutton.cpp bookmarksbutton.cpp \ +- browserbutton.cpp \ ++ browserbutton.cpp knewbutton.cpp \ + desktopbutton.cpp extensionbutton.cpp kbutton.cpp \ + nonkdeappbutton.cpp servicemenubutton.cpp urlbutton.cpp \ + windowlistbutton.cpp +--- applets/media/mediumbutton.cpp (Revision 849788) ++++ applets/media/mediumbutton.cpp (Revision 849791) +@@ -45,7 +45,8 @@ + #include + + MediumButton::MediumButton(QWidget *parent, const KFileItem &fileItem) +- : PanelPopupButton(parent), mActions(this, this), mFileItem(fileItem) ++ : PanelPopupButton(parent), mActions(this, this), mFileItem(fileItem), mOpenTimer(0, ++ "MediumButton::mOpenTimer") + { + KAction *a = KStdAction::paste(this, SLOT(slotPaste()), + &mActions, "pasteto"); +@@ -74,9 +75,9 @@ + + MediumButton::~MediumButton() + { +- QPopupMenu *menu = popup(); +- setPopup(0); +- delete menu; ++ QPopupMenu *menu = static_cast(popup()); ++ setPopup(0); ++ delete menu; + } + + const KFileItem &MediumButton::fileItem() const +@@ -94,29 +95,29 @@ + + void MediumButton::initPopup() + { +- QPopupMenu *old_popup = popup(); +- +- KFileItemList items; +- items.append(&mFileItem); +- +- KonqPopupMenu::KonqPopupFlags kpf = +- KonqPopupMenu::ShowProperties +- | KonqPopupMenu::ShowNewWindow; +- +- KParts::BrowserExtension::PopupFlags bef = +- KParts::BrowserExtension::DefaultPopupItems; +- +- KonqPopupMenu *new_popup = new KonqPopupMenu(0L, items, +- KURL("media:/"), mActions, 0L, +- this, kpf, bef); +- KPopupTitle *title = new KPopupTitle(new_popup); +- title->setTitle(mFileItem.text()); +- +- new_popup->insertItem(title, -1, 0); +- +- setPopup(new_popup); +- +- if (old_popup!=0L) delete old_popup; ++ QPopupMenu *old_popup = static_cast(popup()); ++ ++ KFileItemList items; ++ items.append(&mFileItem); ++ ++ KonqPopupMenu::KonqPopupFlags kpf = ++ KonqPopupMenu::ShowProperties ++ | KonqPopupMenu::ShowNewWindow; ++ ++ KParts::BrowserExtension::PopupFlags bef = ++ KParts::BrowserExtension::DefaultPopupItems; ++ ++ KonqPopupMenu *new_popup = new KonqPopupMenu(0L, items, ++ KURL("media:/"), mActions, 0L, ++ this, kpf, bef); ++ KPopupTitle *title = new KPopupTitle(new_popup); ++ title->setTitle(mFileItem.text()); ++ ++ new_popup->insertItem(title, -1, 0); ++ ++ setPopup(new_popup); ++ ++ if (old_popup!=0L) delete old_popup; + } + + void MediumButton::refreshType() +--- applets/naughty/NaughtyProcessMonitor.cpp (Revision 849788) ++++ applets/naughty/NaughtyProcessMonitor.cpp (Revision 849791) +@@ -94,7 +94,7 @@ + d = new NaughtyProcessMonitorPrivate; + d->interval_ = interval * 1000; + d->triggerLevel_ = triggerLevel; +- d->timer_ = new QTimer(this); ++ d->timer_ = new QTimer(this, "NaughtyProcessMonitorPrivate::timer"); + connect(d->timer_, SIGNAL(timeout()), this, SLOT(slotTimeout())); + } + +--- applets/launcher/quicklauncher.cpp (Revision 849788) ++++ applets/launcher/quicklauncher.cpp (Revision 849791) +@@ -110,7 +110,7 @@ + m_configAction = new KAction(i18n("Configure Quicklauncher..."), "configure", KShortcut(), + this, SLOT(slotConfigure()), this); + +- m_saveTimer = new QTimer(this); ++ m_saveTimer = new QTimer(this, "m_saveTimer"); + connect(m_saveTimer, SIGNAL(timeout()), this, SLOT(saveConfig())); + + m_popularity = new PopularityStatistics(); +--- applets/trash/trashbutton.cpp (Revision 849788) ++++ applets/trash/trashbutton.cpp (Revision 849791) +@@ -78,7 +78,7 @@ + + void TrashButton::initPopup() + { +- QPopupMenu *old_popup = popup(); ++ QPopupMenu *old_popup = static_cast(popup()); + + KFileItemList items; + items.append(&mFileItem); +--- applets/systemtray/systemtrayapplet.cpp (Revision 849788) ++++ applets/systemtray/systemtrayapplet.cpp (Revision 849791) +@@ -375,7 +375,7 @@ + connect(m_expandButton, SIGNAL(clicked()), + this, SLOT(toggleExpanded())); + +- m_autoRetractTimer = new QTimer(this); ++ m_autoRetractTimer = new QTimer(this, "m_autoRetractTimer"); + connect(m_autoRetractTimer, SIGNAL(timeout()), + this, SLOT(checkAutoRetract())); + } +--- applets/clock/clock.cpp (Revision 849788) ++++ applets/clock/clock.cpp (Revision 849791) +@@ -863,8 +863,8 @@ + _calendar(0), + _disableCalendar(false), + _clock(0), +- _timer(new QTimer(this)), +- m_layoutTimer(new QTimer(this)), ++ _timer(new QTimer(this, "ClockApplet::_timer")), ++ m_layoutTimer(new QTimer(this, "m_layoutTimer")), + m_layoutDelay(0), + m_followBackgroundSetting(true), + m_dateFollowBackgroundSetting(true), +--- applets/minipager/pagerbutton.cpp (Revision 849788) ++++ applets/minipager/pagerbutton.cpp (Revision 849791) +@@ -70,6 +70,8 @@ + m_bgPixmap(0), + m_isCommon(false), + m_currentWindow(0), ++ m_updateCompressor(0, "KMiniPagerButton::updateCompressor"), ++ m_dragSwitchTimer(0, "KMiniPagerButton::dragSwitchTimer"), + m_inside(false) + { + setToggleButton(true); +--- data/kmenu_side/Makefile.am (Revision 849788) ++++ data/kmenu_side/Makefile.am (Revision 849791) +@@ -1,6 +1,5 @@ +-kicker_kmenuside_pics_data_DATA = kside.png kside_tile.png ++kicker_kmenuside_pics_data_DATA = kside.png kside_tile.png ++kicker_kmenuside_pics_datadir = $(kde_datadir)/kicker/pics + +-kicker_kmenuside_pics_datadir = $(kde_datadir)/kicker/pics/ +- + EXTRA_DIST = $(kicker_kmenuside_pics_data_DATA) + +--- data/Makefile.am (Revision 849788) ++++ data/Makefile.am (Revision 849791) +@@ -1 +1 @@ +-SUBDIRS = icons tiles app_start_anim wallpaper kmenu_side ++SUBDIRS = icons tiles app_start_anim wallpaper kmenu_side kickoff +Kann nicht anzeigen: Dateityp ist als binär angegeben. +svn:mime-type = application/octet-stream + +Eigenschaftsänderungen: data/kickoff/cr32-action-suspend2disk.png +___________________________________________________________________ +Hinzugefügt: svn:mime-type + + application/octet-stream + +Kann nicht anzeigen: Dateityp ist als binär angegeben. +svn:mime-type = application/octet-stream + +Eigenschaftsänderungen: data/kickoff/search-tab-left.png +___________________________________________________________________ +Hinzugefügt: svn:mime-type + + application/octet-stream + +Kann nicht anzeigen: Dateityp ist als binär angegeben. +svn:mime-type = application/octet-stream + +Eigenschaftsänderungen: data/kickoff/main_corner_tr.png +___________________________________________________________________ +Hinzugefügt: svn:mime-type + + application/octet-stream + +Kann nicht anzeigen: Dateityp ist als binär angegeben. +svn:mime-type = application/octet-stream + +Eigenschaftsänderungen: data/kickoff/cr48-app-recently_used.png +___________________________________________________________________ +Hinzugefügt: svn:mime-type + + application/octet-stream + +Kann nicht anzeigen: Dateityp ist als binär angegeben. +svn:mime-type = application/octet-stream + +Eigenschaftsänderungen: data/kickoff/search-tab-top-left.png +___________________________________________________________________ +Hinzugefügt: svn:mime-type + + application/octet-stream + +Kann nicht anzeigen: Dateityp ist als binär angegeben. +svn:mime-type = application/octet-stream + +Eigenschaftsänderungen: data/kickoff/right_triangle.png +___________________________________________________________________ +Hinzugefügt: svn:mime-type + + application/octet-stream + +Kann nicht anzeigen: Dateityp ist als binär angegeben. +svn:mime-type = application/octet-stream + +Eigenschaftsänderungen: data/kickoff/cr16-action-suspend2disk.png +___________________________________________________________________ +Hinzugefügt: svn:mime-type + + application/octet-stream + +Kann nicht anzeigen: Dateityp ist als binär angegeben. +svn:mime-type = application/octet-stream + +Eigenschaftsänderungen: data/kickoff/crsc-action-suspend2ram.svgz +___________________________________________________________________ +Hinzugefügt: svn:mime-type + + application/octet-stream + +Kann nicht anzeigen: Dateityp ist als binär angegeben. +svn:mime-type = application/octet-stream + +Eigenschaftsänderungen: data/kickoff/cr128-action-suspend2ram.png +___________________________________________________________________ +Hinzugefügt: svn:mime-type + + application/octet-stream + +Kann nicht anzeigen: Dateityp ist als binär angegeben. +svn:mime-type = application/octet-stream + +Eigenschaftsänderungen: data/kickoff/cr32-action-leave.png +___________________________________________________________________ +Hinzugefügt: svn:mime-type + + application/octet-stream + +Kann nicht anzeigen: Dateityp ist als binär angegeben. +svn:mime-type = application/octet-stream + +Eigenschaftsänderungen: data/kickoff/left_triangle.png +___________________________________________________________________ +Hinzugefügt: svn:mime-type + + application/octet-stream + +Kann nicht anzeigen: Dateityp ist als binär angegeben. +svn:mime-type = application/octet-stream + +Eigenschaftsänderungen: data/kickoff/menu_separator.png +___________________________________________________________________ +Hinzugefügt: svn:mime-type + + application/octet-stream + +Kann nicht anzeigen: Dateityp ist als binär angegeben. +svn:mime-type = application/octet-stream + +Eigenschaftsänderungen: data/kickoff/cr32-action-suspend2ram.png +___________________________________________________________________ +Hinzugefügt: svn:mime-type + + application/octet-stream + +Kann nicht anzeigen: Dateityp ist als binär angegeben. +svn:mime-type = application/octet-stream + +Eigenschaftsänderungen: data/kickoff/cr48-action-leave.png +___________________________________________________________________ +Hinzugefügt: svn:mime-type + + application/octet-stream + +Kann nicht anzeigen: Dateityp ist als binär angegeben. +svn:mime-type = application/octet-stream + +Eigenschaftsänderungen: data/kickoff/cr16-action-suspend2ram.png +___________________________________________________________________ +Hinzugefügt: svn:mime-type + + application/octet-stream + +Kann nicht anzeigen: Dateityp ist als binär angegeben. +svn:mime-type = application/octet-stream + +Eigenschaftsänderungen: data/kickoff/search-tab-top-center.png +___________________________________________________________________ +Hinzugefügt: svn:mime-type + + application/octet-stream + +Kann nicht anzeigen: Dateityp ist als binär angegeben. +svn:mime-type = application/octet-stream + +Eigenschaftsänderungen: data/kickoff/search-tab-center.png +___________________________________________________________________ +Hinzugefügt: svn:mime-type + + application/octet-stream + +Kann nicht anzeigen: Dateityp ist als binär angegeben. +svn:mime-type = application/octet-stream + +Eigenschaftsänderungen: data/kickoff/cr64-action-suspend2ram.png +___________________________________________________________________ +Hinzugefügt: svn:mime-type + + application/octet-stream + +Kann nicht anzeigen: Dateityp ist als binär angegeben. +svn:mime-type = application/octet-stream + +Eigenschaftsänderungen: data/kickoff/cr48-action-suspend2ram.png +___________________________________________________________________ +Hinzugefügt: svn:mime-type + + application/octet-stream + +Kann nicht anzeigen: Dateityp ist als binär angegeben. +svn:mime-type = application/octet-stream + +Eigenschaftsänderungen: data/kickoff/search-gradient.png +___________________________________________________________________ +Hinzugefügt: svn:mime-type + + application/octet-stream + +Kann nicht anzeigen: Dateityp ist als binär angegeben. +svn:mime-type = application/octet-stream + +Eigenschaftsänderungen: data/kickoff/crsc-action-leave.svgz +___________________________________________________________________ +Hinzugefügt: svn:mime-type + + application/octet-stream + +Kann nicht anzeigen: Dateityp ist als binär angegeben. +svn:mime-type = application/octet-stream + +Eigenschaftsänderungen: data/kickoff/kmenu_vertical.mng +___________________________________________________________________ +Hinzugefügt: svn:mime-type + + application/octet-stream + +Kann nicht anzeigen: Dateityp ist als binär angegeben. +svn:mime-type = application/octet-stream + +Eigenschaftsänderungen: data/kickoff/cr64-action-suspend2disk.png +___________________________________________________________________ +Hinzugefügt: svn:mime-type + + application/octet-stream + +Kann nicht anzeigen: Dateityp ist als binär angegeben. +svn:mime-type = application/octet-stream + +Eigenschaftsänderungen: data/kickoff/cr48-action-suspend2disk.png +___________________________________________________________________ +Hinzugefügt: svn:mime-type + + application/octet-stream + +Kann nicht anzeigen: Dateityp ist als binär angegeben. +svn:mime-type = application/octet-stream + +Eigenschaftsänderungen: data/kickoff/resize_handle.png +___________________________________________________________________ +Hinzugefügt: svn:mime-type + + application/octet-stream + +Kann nicht anzeigen: Dateityp ist als binär angegeben. +svn:mime-type = application/octet-stream + +Eigenschaftsänderungen: data/kickoff/kmenu_basic.mng +___________________________________________________________________ +Hinzugefügt: svn:mime-type + + application/octet-stream + +Kann nicht anzeigen: Dateityp ist als binär angegeben. +svn:mime-type = application/octet-stream + +Eigenschaftsänderungen: data/kickoff/kmenu_flipped.mng +___________________________________________________________________ +Hinzugefügt: svn:mime-type + + application/octet-stream + +Kann nicht anzeigen: Dateityp ist als binär angegeben. +svn:mime-type = application/octet-stream + +Eigenschaftsänderungen: data/kickoff/search-running.mng +___________________________________________________________________ +Hinzugefügt: svn:mime-type + + application/octet-stream + +Kann nicht anzeigen: Dateityp ist als binär angegeben. +svn:mime-type = application/octet-stream + +Eigenschaftsänderungen: data/kickoff/search-tab-right.png +___________________________________________________________________ +Hinzugefügt: svn:mime-type + + application/octet-stream + +Kann nicht anzeigen: Dateityp ist als binär angegeben. +svn:mime-type = application/octet-stream + +Eigenschaftsänderungen: data/kickoff/search-tab-top-right.png +___________________________________________________________________ +Hinzugefügt: svn:mime-type + + application/octet-stream + +--- data/kickoff/Makefile.am (Revision 0) ++++ data/kickoff/Makefile.am (Revision 849791) +@@ -0,0 +1,14 @@ ++kicker_kmenuside_pics_data_DATA = resize_handle.png \ ++ main_corner_tl.png main_corner_tr.png search-gradient.png \ ++ menu_separator.png search-tab-center.png search-tab-left.png \ ++ search-tab-right.png search-tab-top-center.png search-tab-top-left.png \ ++ left_triangle.png right_triangle.png \ ++ kmenu_basic.mng kmenu_flipped.mng kmenu_vertical.mng \ ++ search-tab-top-right.png search-gradient-topdown.png search-running.mng ++ ++kicker_kmenuside_pics_datadir = $(kde_datadir)/kicker/pics ++ ++EXTRA_DIST = $(kicker_kmenuside_pics_data_DATA) ++ ++kickerdir = $(kde_datadir)/kicker/icons ++kicker_ICON = leave recently_used suspend2disk suspend2ram +Kann nicht anzeigen: Dateityp ist als binär angegeben. +svn:mime-type = application/octet-stream + +Eigenschaftsänderungen: data/kickoff/cr128-action-suspend2disk.png +___________________________________________________________________ +Hinzugefügt: svn:mime-type + + application/octet-stream + +Kann nicht anzeigen: Dateityp ist als binär angegeben. +svn:mime-type = application/octet-stream + +Eigenschaftsänderungen: data/kickoff/crsc-action-suspend2disk.svgz +___________________________________________________________________ +Hinzugefügt: svn:mime-type + + application/octet-stream + +Kann nicht anzeigen: Dateityp ist als binär angegeben. +svn:mime-type = application/octet-stream + +Eigenschaftsänderungen: data/kickoff/search-gradient-topdown.png +___________________________________________________________________ +Hinzugefügt: svn:mime-type + + application/octet-stream + +Kann nicht anzeigen: Dateityp ist als binär angegeben. +svn:mime-type = application/octet-stream + +Eigenschaftsänderungen: data/kickoff/main_corner_tl.png +___________________________________________________________________ +Hinzugefügt: svn:mime-type + + application/octet-stream + + +Eigenschaftsänderungen: data/kickoff +___________________________________________________________________ +Hinzugefügt: svn:ignore + + Makefile +Makefile.in + + -- cgit v1.2.1