Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:11.4
kdebase3
kickoff.diff
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File kickoff.diff of Package kdebase3
--- 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 @@ <label>A list of extensions that have been loaded at runtime. In the case of a crash these extensions will not be loaded at the next Kicker start, in case they caused the crash</label> </entry> +<entry name="LegacyKMenu" type="Bool" > + <label>When this option is enabled, the classic K Menu is used.</label> + <default>false</default> + </entry> + +<entry name="OpenOnHover" type="Bool" > + <label>When this option is enabled, the SUSE Menu does open on mouse hover.</label> + <default>true</default> + </entry> + +<entry name="ScrollFlipView" type="Bool" > + <label>When this option is enabled, the SUSE Menu application view switching will scroll.</label> + <default>true</default> + </entry> + +<entry name="KMenuWidth" type="Int"> + <label>Preferred width of the KMenu</label> + <default>0</default> + </entry> + +<entry name="KMenuHeight" type="Int"> + <label>Preferred width of the KMenu</label> + <default>0</default> + </entry> + +<entry name="KickoffFontPointSizeOffset" type="Int" > + <label>With this option the scale of the fonts Kickoff uses can be influenced</label> + <default>0</default> + <min>-100</min> + <max>100</max> + </entry> + +<entry name="KickoffSearchAddressBook" type="Bool" > + <label>When this option is enabled, kabc is utilized to search for addresses. This may start KMail.</label> + <default>false</default> + </entry> + +<entry name="KickoffDrawGeekoEye" type="Bool" > + <label>When this option is enabled, the Geeko eye moves when the mouse hovers the start menu button</label> + <default>false</default> + </entry> + +<entry name="KickoffTabBarFormat" type="Enum" > + <choices> + <choice name="LabelAndIcon"> + <label>Show names and icons on tabs</label> + </choice> + <choice name="LabelOnly"> + <label>Show only the names</label> + </choice> + <choice name="IconOnly"> + <label>Show only the icons</label> + </choice> + </choices> + <default>LabelAndIcon</default> + <label>Appearace of the Kickoff tabbar</label> + </entry> + +<entry name="KickoffSwitchTabsOnHover" type="Bool" > + <label>When this option is enabled, the tabs in the Kickoff menu will switch without the need to click</label> + <default>true</default> + </entry> + + </group> <group name="menus"> @@ -172,6 +236,19 @@ <default>false</default> </entry> +<entry name="Favorites" type="StringList"> + <label>The menu entries shown in the Favorites tab</label> + </entry> + +<entry name="FirstRun" type="Bool" > + <label>Whether the panel has been started before or not</label> + <default>false</default> + </entry> + +<entry name="FirstSeenApps" type="StringList"> + <label>When the applications were first seen by Kickoff</label> + </entry> + </group> <group name="button_tiles"> @@ -337,6 +414,29 @@ </group> + <group name="SearchField"> + <entry key="History" type="PathList"> + <default></default> + <label></label> + <whatsthis></whatsthis> + </entry> + <entry key="HistoryLength" type="Int"> + <default>50</default> + <label></label> + <whatsthis></whatsthis> + </entry> + <entry key="CompletionItems" type="PathList"> + <default></default> + <label></label> + <whatsthis></whatsthis> + </entry> + <entry key="CompletionMode" type="Int"> + <default>2</default> + <label></label> + <whatsthis></whatsthis> + </entry> + </group> + </kcfg> --- libkicker/kickertip.cpp (Revision 849788) +++ libkicker/kickertip.cpp (Revision 849791) @@ -38,6 +38,7 @@ // putting this #include higher results in compile errors #include <netwm.h> +#include <assert.h> 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 <kipc.h> #include <kstandarddirs.h> #include <klocale.h> +#include <kdebug.h> #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<QPopupMenu*>(m_popup)) + static_cast<QPopupMenu*>(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 <binner@kde.org> * + * Copyright (c) 2006 Debajyoti Bera <dbera.web@gmail.com> * + * * + * 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 <qobject.h> +#include <kurl.h> +#include <kservice.h> + +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 <binner@kde.org> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; 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 <binner@kde.org> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; 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 <qobject.h> + +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 <binner@kde.org> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; 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 <qobjectlist.h> + +KickoffSearch::Plugin::Plugin(QObject *parent, const char* name ) + :QObject( parent, name ) +{ +} + +KickoffSearch::Plugin::~Plugin() +{ +} + +KickoffSearch::KickoffSearchInterface* KickoffSearch::Plugin::kickoffSearchInterface() +{ + return static_cast<KickoffSearchInterface*>( 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 <qvaluelist.h> class PanelKMenu; +class KMenu; class KickerClientMenu; +class KMenuStub; class PanelPopupButton; typedef QValueList<PanelPopupButton*> 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<KickerClientMenu*> 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<QWidget*>(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 <wstephenson@novell.com> + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +******************************************************************/ + +#include <qapplication.h> +#include <qhbox.h> +#include <qheader.h> +#include <assert.h> + +#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<KMenuItem*>(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 <binner@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + +******************************************************************/ + +#include "query.h" +#include <kdebug.h> + +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;index<term.length();index++) { + if (current_part.isEmpty() && query_term[index]=='-') + exclude_part = true; + else if (term[index]=='\'' || term[index]=='"') { + if (within_quotes) + add_term(); + else + within_quotes = true; + } + else if (!within_quotes && query_term[index]==' ') + add_term(); + else if (!exclude_part && !within_quotes && query_term[index]=='O' && index+1<term.length() && query_term[index+1]=='R') { + index++; + alternatives.append(current_alternative); + current_alternative = new Alternative; + within_quotes = false; + exclude_part = false; + current_part = QString::null; + } + else + current_part+=term[index]; + } + add_term(); + alternatives.append(current_alternative); + +#if 0 + for (Alternative* alt=alternatives.first(); alt; alt=alternatives.next()) { + kdDebug() << "---" << endl; + kdDebug() << "*** includes = " << alt->includes << endl; + kdDebug() << "*** excludes = " << alt->excludes << endl; + } +#endif +} + +void Query::add_term() { + if (!current_part.isEmpty()) { + if (current_part.startsWith("*")) + current_part=current_part.mid(1); + + if (current_part.endsWith("*")) + current_part=current_part.mid(0,current_part.length()-1); + + if (exclude_part) + current_alternative->excludes+=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 <dbera.web@gmail.com> + Copyright (c) 2006 Dirk Mueller <mueller@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + +******************************************************************/ + +#include <stdlib.h> +#include <sys/types.h> +#include <unistd.h> +#include <dmctl.h> +#include <inttypes.h> + +#include <qimage.h> +#include <qpainter.h> +#include <qstyle.h> +#include <qwidgetstack.h> +#include <qlayout.h> +#include <qlabel.h> +#include <qregexp.h> +#include <qfile.h> +#include <qstylesheet.h> +#include <qaccel.h> +#include <qcursor.h> +#include <qdir.h> +#include <qsimplerichtext.h> +#include <qtooltip.h> +#include <qtabbar.h> + +#include <dcopclient.h> +#include <kapplication.h> +#include <kaboutkde.h> +#include <kaction.h> +#include <kbookmarkmenu.h> +#include <kconfig.h> +#include <kdebug.h> +#include <kglobal.h> +#include <kglobalsettings.h> +#include <kiconloader.h> +#include <klineedit.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <kstandarddirs.h> +#include <kcombobox.h> +#include <kwin.h> +#include <kdebug.h> +#include <kuser.h> +#include <kurllabel.h> +#include <krun.h> +#include <kmimetype.h> +#include <krecentdocument.h> +#include <kcompletionbox.h> +#include <kurifilter.h> +#include <kbookmarkmanager.h> +#include <kbookmark.h> +#include <kprocess.h> +#include <kio/jobclasses.h> +#include <kio/job.h> +#include <dcopref.h> +#include <konq_popupmenu.h> +#include <konqbookmarkmanager.h> +#include <kparts/componentfactory.h> + +#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 <dmctl.h> +#include <sys/vfs.h> +#include <mykickoffsearchinterface.h> + +#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("<u>","&"); + 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 <assert.h> + +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 <b>%1</b> on <b>%2</b>" ) + .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, "<qt>" + i18n( "Most commonly used applications and documents" ) + "</qt>" ); + m_tabs[ApplicationsTab] = new QTab; + m_tabBar->addTab(m_tabs[ApplicationsTab]); + m_tabBar->setToolTip(ApplicationsTab, "<qt>" + i18n( "List of installed applications" ) + + "</qt>" ); + + m_tabs[ComputerTab] = new QTab; + m_tabBar->addTab(m_tabs[ComputerTab]); + m_tabBar->setToolTip(ComputerTab, "<qt>" + i18n( "Information and configuration of your " + "system, access to personal files, network resources and connected disk drives") + + "</qt>"); +#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, "<qt>" + i18n( "Recently used applications and documents" ) + + "</qt>" ); + m_tabs[LeaveTab] = new QTab; + m_tabBar->addTab(m_tabs[LeaveTab]); + m_tabBar->setToolTip(LeaveTab, i18n("<qt>Logout, switch user, switch off or reset," + " suspend of the system" ) + "</qt>" ); + + if (KickerSettings::kickoffTabBarFormat() != KickerSettings::IconOnly) { + m_tabs[FavoriteTab]->setText(workaroundStringFreeze(i18n("<p align=\"center\"> <u>F</u>avorites</p>"))); + m_tabs[HistoryTab]->setText(workaroundStringFreeze(i18n("<p align=\"center\"><u>H</u>istory</p>"))); + m_tabs[ComputerTab]->setText( + workaroundStringFreeze(i18n("<p align=\"center\"> <u>C</u>omputer</p>"))); + m_tabs[ApplicationsTab]->setText(workaroundStringFreeze(i18n("<p align=\"center\"><u>A</u>pplications</p>"))); + m_tabs[LeaveTab]->setText( + workaroundStringFreeze(i18n("<p align=\"center\"><u>L</u>eave</p>"))); + } + + 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<KLineEdit*>(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<QMouseEvent*>(e); + p = me->globalPos(); + } + else if (e->type() == QEvent::Wheel) { + QWheelEvent* we = static_cast<QWheelEvent*>(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<QWidget*>(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<QWidget*>(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<QWidget*>(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<ItemView*>(m_stacker->visibleWidget()); + + if (view) + { + bool handled = true; + switch (static_cast<QKeyEvent*>(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<KMenuItem*>(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<FlipScrollView*>(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<FlipScrollView*>(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<QScrollView*>(raiseWidget)) + // m_activeTab->setFocusProxy(static_cast<QScrollView*>(raiseWidget)->viewport()); + + if (0 && /*raiseWidget == m_stacker->visibleWidget() &&*/ !raiseWidget->hasFocus()) { + + if (dynamic_cast<QScrollView*>(raiseWidget)) + static_cast<QScrollView*>(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<ItemView*>(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<KSharedPtr<KSycocaEntry>,QCString> slist; + KSortableValueList<KSharedPtr<KSycocaEntry>,QCString> glist; + QMap<QString,QString> specialTitle; + QMap<QString,QString> categoryIcon; + QMap<QString,QString> shortenedMenuPath; +#endif + + for (; it != _list.end(); ++it) + { + KSycocaEntry * e = *it; + + if (e->isType(KST_KServiceGroup)) + { + KServiceGroup::Ptr g(static_cast<KServiceGroup *>(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<KService *>(_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<KService *>(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<KServiceGroup *>(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<KService *>(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<KSycocaEntry*>(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<KService *>(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("<p>You have chosen to open another desktop session.<br>" + "The current session will be hidden " + "and a new login screen will be displayed.<br>" + "An F-key is assigned to each session; " + "F%1 is usually assigned to the first session, " + "F%2 to the second session and so on. " + "You can switch between sessions by pressing " + "Ctrl, Alt and the appropriate F-key at the same time. " + "Additionally, the KDE Panel and Desktop menus have " + "actions for switching between sessions.</p>") + .arg(7).arg(8), + i18n("Warning - New Session"), + KGuiItem(i18n("&Start New Session"), "fork"), + ":confirmNewSession", + KMessageBox::PlainCaption | KMessageBox::Notify); + + if (result==KMessageBox::Cancel) + return; + + if (lock) + slotLock(); + + DM().startReserve(); +} + +void 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("<center><b>%1</b></center>\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("<center><b>%1</b></center>\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("<center><b>%1</b></center>\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()<screen.height()/2) + ? TopDown : BottomUp); + } + + m_browserDirty=true; + m_recentDirty=true; + + updateMedia(); + m_mediaFreeTimer.start(10 * 1000); // refresh all 10s + + m_stacker->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<QString>::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<KServiceGroup *>(e)); + if(!g->noDisplay()) + createNewProgramList(g->relPath()); + } else if(e->isType(KST_KService)) { + KService::Ptr s(static_cast<KService *>(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<KServiceGroup *>(e)); + if(!g->noDisplay()) + searchProgramList(g->relPath()); + } else if(e->isType(KST_KService)) { + KService::Ptr s(static_cast<KService *>(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<KickoffSearch::Plugin> + ( 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; i<num_categories; ++i) { + categorised_hit_total [i] = 0; + max_category_id [i] = base_category_id [i]; + } +} + +void KMenu::doQuery (bool return_pressed) +{ + QString query_str = m_kcommand->lineEdit()->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; i<num_categories; ++i) + already_added [i] = (max_category_id [i] != base_category_id [i]); +} + +void KMenu::updateCategoryTitles() +{ + // update category title + for (int i=0; i<num_categories; ++i) { + if (i == OTHER) + continue; + // nothing is in this category + if (max_category_id [i] == base_category_id [i]) + continue; + + KMenuItemSeparator *sep = 0; + + // if nothing was in this category before but now there is + if (! already_added [i]) { + // insert a new title for this category + int index = getHitMenuItemPosition (new HitMenuItem ( + base_category_id[i], + i)); + QString title = QString ("%1").arg (i18n(categories [i].utf8())); + sep = m_searchResultsWidget->insertSeparator(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<KMenuItemSeparator*>( 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<KMenuItem*>(item); + if (!kitem) + return; + + KFileItemList _items; + _items.setAutoDelete(true); + + if (dynamic_cast<KMenuItemSeparator*>(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<KMenuItem*>(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<KMenuItem*>(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<HitMenuItem> 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<HitMenuItem> 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<KMenuItem*>(item); + KMenuItem* kafterNow = dynamic_cast<KMenuItem*>(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<KMenuSpacer*>(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 <liblazy.h> +#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 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>KMenuItemBase</class> +<widget class="QWidget"> + <property name="name"> + <cstring>KMenuItemBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>514</width> + <height>80</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>32767</width> + <height>80</height> + </size> + </property> + <property name="caption"> + <string>KMenuItemBase</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>2</number> + </property> + <widget class="QLayoutWidget" row="0" column="1"> + <property name="name"> + <cstring>layout11</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>itemTitle</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>1</vsizetype> + <horstretch>1</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="font"> + <font> + <pointsize>14</pointsize> + </font> + </property> + <property name="text"> + <string></string> + </property> + <property name="textFormat"> + <enum>RichText</enum> + </property> + <property name="alignment"> + <set>WordBreak|AlignTop</set> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>itemDescription</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>0</horstretch> + <verstretch>1</verstretch> + </sizepolicy> + </property> + <property name="paletteForegroundColor"> + <color> + <red>188</red> + <green>188</green> + <blue>188</blue> + </color> + </property> + <property name="text"> + <string></string> + </property> + <property name="textFormat"> + <enum>RichText</enum> + </property> + <property name="alignment"> + <set>WordBreak|AlignTop</set> + </property> + </widget> + </vbox> + </widget> + <widget class="QLayoutWidget" row="0" column="0"> + <property name="name"> + <cstring>layout4</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>itemPixmap</cstring> + </property> + <property name="minimumSize"> + <size> + <width>64</width> + <height>64</height> + </size> + </property> + <property name="text"> + <string></string> + </property> + <property name="alignment"> + <set>AlignTop|AlignHCenter</set> + </property> + </widget> + </vbox> + </widget> + </grid> +</widget> +<layoutdefaults spacing="6" margin="11"/> +</UI> --- 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 <mueller@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + +******************************************************************/ + +#include "kickoff_bar.h" +#include "itemview.h" + +#include <qiconset.h> +#include <qpainter.h> +#include <qcursor.h> +#include <qstyle.h> +#include <qapplication.h> + +#include <kdebug.h> +#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 <coolo@novell.com> + +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 <dcopobject.h> +#include <qobject.h> +#include <qstringlist.h> + +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 <wstephenson@novell.com> + +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 <qscrollview.h> +#include <qlistview.h> +#include <qframe.h> +#include <qtimer.h> +#include <qpainter.h> +#include <kstandarddirs.h> +#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 <dbera.web@gmail.com> + + 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 <dcopobject.h> +#include <qintdict.h> +#include <qpixmap.h> +#include <qframe.h> +#include <qtoolbutton.h> +#include <qscrollview.h> +#include <qtimer.h> +#include <qbitmap.h> +#include <qvbox.h> +#include <qregexp.h> + +#include <kabc/addressbook.h> +#include <kabc/stdaddressbook.h> +#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<KickerClientMenu> 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<QString, QString> mimetype_iconstore; + QMap<QString, QString> 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<HitMenuItem> 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<HitMenuItem> 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 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>KMenuBase</class> +<widget class="QDialog"> + <property name="name"> + <cstring>KMenu</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>723</width> + <height>580</height> + </rect> + </property> + <property name="caption"> + <string>KMenu</string> + </property> + <property name="frameShadow" stdset="0"> + <string>MShadow</string> + </property> + <property name="frameShape" stdset="0"> + <string>MShape</string> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>m_search</cstring> + </property> + <property name="geometry"> + <rect> + <x>20</x> + <y>40</y> + <width>190</width> + <height>54</height> + </rect> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>0</number> + </property> + <widget class="QFrame"> + <property name="name"> + <cstring>m_searchFrame</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>52</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>32767</width> + <height>52</height> + </size> + </property> + <property name="frameShape"> + <enum>StyledPanel</enum> + </property> + <property name="frameShadow"> + <enum>Raised</enum> + </property> + <property name="lineWidth"> + <number>0</number> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout18</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>m_searchLabel</cstring> + </property> + <property name="backgroundOrigin"> + <enum>ParentOrigin</enum> + </property> + <property name="font"> + <font> + <pointsize>14</pointsize> + </font> + </property> + <property name="text"> + <string>Search:</string> + </property> + </widget> + <widget class="KHistoryCombo"> + <property name="name"> + <cstring>m_kcommand</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>m_searchPixmap</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>1</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>32</width> + <height>32</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>32</width> + <height>32</height> + </size> + </property> + <property name="backgroundMode"> + <enum>PaletteBackground</enum> + </property> + <property name="backgroundOrigin"> + <enum>ParentOrigin</enum> + </property> + <property name="scaledContents"> + <bool>true</bool> + </property> + </widget> + </hbox> + </widget> + </hbox> + </widget> + <spacer> + <property name="name"> + <cstring>spacer5_2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Preferred</enum> + </property> + <property name="sizeHint"> + <size> + <width>16</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>m_footer</cstring> + </property> + <property name="geometry"> + <rect> + <x>20</x> + <y>110</y> + <width>407</width> + <height>34</height> + </rect> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>4</number> + </property> + <property name="spacing"> + <number>4</number> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>m_userInfo</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>User&nbsp;<b>user</b>&nbsp;on&nbsp;<b>host</b></string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer13_2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>MinimumExpanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>10</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QToolButton"> + <property name="name"> + <cstring>m_branding</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>4</hsizetype> + <vsizetype>4</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>90</width> + <height>24</height> + </size> + </property> + <property name="text"> + <string></string> + </property> + <property name="iconSet"> + <iconset>image0</iconset> + </property> + <property name="usesBigPixmap"> + <bool>true</bool> + </property> + <property name="autoRaise"> + <bool>true</bool> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer13</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>14</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> +</widget> +<customwidgets> +</customwidgets> +<images> + <image name="image0"> + <data format="XPM.GZ" length="2522">789cdd933d6fdb30104077ff0a21de8c82b12d5bb2507448f6021d0b141dc82369d9116d7d50b1ada2ffbdbca3c4444950244032b4b790efce7cd29de8eb59f4fddbd768763d692cb73b8820e7753493ad31971f3fbffc9a5c6d36d17219c5f36871f56972e57e104dd7324be325a2464cd24cc60a5120a6731eaf046241c879b64e113bc44dcc751223da802bc41de16ac092508a753a4754885922440a8892301332a5e79e10f91c169b0cf1963083345b231a423ee0bec78dc71c51c420393578249432e664be2354d2bd17628d0889cc0447bc20cab9d490205601a9df29e142cd3d9e0933b59234ba0321576b49d3d8f69878bc41544b952a6abf218c9590f41a9c70a5c0e33d21e885a2e1b4883ad1a9de2032420ac20f8affde3df5415bdea7f8b8c0fbed507fa59b0bf02119739f9172b46e755fc819dbf55bd07ba15fef0ec7f6b41f728c0dcf84bbc76ebedfbfde0d2042eb8fdd5b801de5b794281e06f716f7ee710f619d5227a1b01b1d0aeedc18e366660ec7b2ac18ab1d1a9745acd1ad3161f28631dbbb716d86c29112c2f86363770ec20a383a89b51a9a06b4b5503a2c10dd771b46d98cdcac180a052528cc13b781b6bd7759506d5b435541ddb6161cba16c0f5a174383872b3729057c19dbfe06ed16ddab642b7324638b77b870add3eaae76e1fb577db17e7fdcc5d586bcd5fddc59bdda7deed7d83db580a81ee93bb906eefd4ee0fa24201ddda53f9d4ad4ce92605fae466713843614ceddd17b83008d1b06618bd2b5e42de3da70b7019dfc1b2eb3af7e140a9ae7342d3d152babb75ee1a76ea7c9478ea5c92bd3bf6c7a870f6677cdc8cdd7d840bf40ef1cc7dfb716efd81eef78c7fd6fdfbf3e40f51236246</data> + </image> +</images> +<includes> + <include location="local" impldecl="in implementation">kmenubase.ui.h</include> +</includes> +<functions> + <function access="private" specifier="non virtual">init()</function> +</functions> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>kcombobox.h</includehint> +</includehints> +</UI> --- 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 <mueller@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + +******************************************************************/ + +#ifndef __kickoff_bar_h__ +#define __kickoff_bar_h__ + +#include <qtabbar.h> + +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 <mueller@kde.org> + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +******************************************************************/ + +#include "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 <X11/Xlib.h> + +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 <binner@kde.org> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; 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 <dcopobject.h> +#include <qintdict.h> +#include <qpixmap.h> +#include <qframe.h> +#include <qtoolbutton.h> +#include <klistview.h> +#include <qdragobject.h> + +#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 <binner@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + +******************************************************************/ + +#ifndef QUERY_H +#define QUERY_H + +#include <qstringlist.h> +#include <qptrlist.h> + +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<Alternative> 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 <mueller@kde.org> + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +******************************************************************/ + +#ifndef __k_mnu_stub_h__ +#define __k_mnu_stub_h__ + +#include <qstring.h> +#include <qpoint.h> + +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 <binner@kde.org> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; 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 <stdlib.h> +#include <sys/types.h> +#include <unistd.h> +#include <dmctl.h> + +#include <qapplication.h> +#include <qimage.h> +#include <qpainter.h> +#include <qstyle.h> +#include <qwidgetstack.h> +#include <qlayout.h> +#include <qlabel.h> +#include <qvbox.h> +#include <qheader.h> +#include <qdrawutil.h> +#include <qdragobject.h> +#include <qcursor.h> +#include <qpaintdevicemetrics.h> +#include <qbuffer.h> +#include <qtooltip.h> +#include <qstylesheet.h> +#include <qiconview.h> + +#include <dcopclient.h> +#include <kapplication.h> +#include <kaboutkde.h> +#include <kpixmapeffect.h> +#include <kaction.h> +#include <kbookmarkmenu.h> +#include <kconfig.h> +#include <kdebug.h> +#include <kglobal.h> +#include <kglobalsettings.h> +#include <kiconloader.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <kstandarddirs.h> +#include <kcombobox.h> +#include <kwin.h> +#include <kdebug.h> +#include <kmimetype.h> +#include <kmultipledrag.h> + +#include "client_mnu.h" +#include "container_base.h" +#include "global.h" +#include "kbutton.h" +#include "kicker.h" +#include "kickerSettings.h" +#include "konqbookmarkmanager.h" +#include "menuinfo.h" +#include "menumanager.h" +#include "popupmenutitle.h" +#include "quickbrowser_mnu.h" +#include "recentapps.h" + +#include "k_mnu.h" +#include "k_new_mnu.h" +#include "itemview.h" + +// -------------------------------------------------------------------------- + +KMenuItem::~KMenuItem() +{ + ItemView *listview = dynamic_cast<ItemView*>( 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<ItemView*>( 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<KMenuItem*>( itemAbove() ); + else + listview->m_lastOne = static_cast<KMenuItem*>( 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 + "<br><br>" + 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 + "<br><br>" + 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<KMenuItem*>( 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<KMenuItem*>(it.current())->id() == nId) + return static_cast<KMenuItem*>(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<KMenuItem*>(lastItem()); + + int i = 1; + QListViewItemIterator it(this); + for (;it.current(); ++i, ++it) { + if(i == nIndex) + return static_cast<KMenuItem*>(it.current()); + } + + return static_cast<KMenuItem*>(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<KMenuSpacer*>( 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<KMenuItem*>(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<KMenuItemSeparator*>( 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<KMenuItemSeparator*>( 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<KMenuItem*>(item); + + if (dynamic_cast<KMenuItemHeader*>(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<KMenuSpacer*>( 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 <coolo@novell.com> + +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 <kapplication.h> +#include <kdebug.h> +#include <dcopclient.h> +#include <dcopref.h> + +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 <binner@kde.org> + Stephan Kulow <coolo@kde.org> + Dirk Mueller <mueller@kde.org> + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +******************************************************************/ + +#include <cassert> +#include <cmath> + +#include <qtooltip.h> +#include <qpainter.h> +#include <qcursor.h> +#include <private/qeffects_p.h> + +#include <klocale.h> +#include <kapplication.h> +#include <kstandarddirs.h> +#include <kiconloader.h> +#include <kdebug.h> + +#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<KNewButton*>(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<KNewButton*>(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<QMouseEvent *>(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<QMouseEvent *>(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<KMenu*>(m_popup)); + + disconnect(dynamic_cast<KMenu*>(m_popup), SIGNAL(aboutToHide()), this, + SLOT(slotStopAnimation())); + connect(dynamic_cast<KMenu*>(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<KMenu*>(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 <binner@kde.org> + Stephan Kulow <coolo@kde.org> + Dirk Mueller <mueller@kde.org> + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +******************************************************************/ + +#ifndef __knewbutton_h__ +#define __knewbutton_h__ + +#include "kbutton.h" + +#include <qmovie.h> +#include <qpoint.h> + +/** + * 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 <konq_drag.h> 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<QPopupMenu*>(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<QPopupMenu*>(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<QPopupMenu*>(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
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor