diff --git a/kcontrol/kicker/kicker_config_hiding.desktop b/kcontrol/kicker/kicker_config_hiding.desktop
index 60c040264..0cf9553b9 100644
--- a/kcontrol/kicker/kicker_config_hiding.desktop
+++ b/kcontrol/kicker/kicker_config_hiding.desktop
@@ -150,7 +150,7 @@ Keywords[csb]=kicker,panel,kpanel,lëstëw zadaniów,sztartowô lëstëw,lëstë
Keywords[cy]=ciciwr,kicker,panel,kpanel,bar tasgau,bar cychwyn,bar lansio,lleoliad,maint,awto-guddio,hunan-guddio,cuddio,botymau,animeiddiad,cefndir,themâu,storfa dewislen, storfa,cache,celc,cudd,K-Menu,nodau tudalen,dogfenni diweddar,porydd cyflym,dewislen porydd,dewislen,eiconau,teiliau,rhaglenigion,ymcychwyn,amlygu,carnau,eiconau chwyddo
Keywords[da]=kicker,panel,kpanel,opgavelinje,startlinje,sted,størrelse,autogem,gem,knapper,animering,baggrund,temaer,menucache,cache,skjult,K-Menu,bogmærker,nylige dokumenter,hurtigsøger,søgemenu,menu,ikoner,fliser,panelprogrammer,opstart,markér,håndterer,ikoner
Keywords[de]=Kicker,Panel,Taskbar,Kontrollleiste,Startleiste,Klickstartleiste,Fensterleiste,Autom. ausblenden,Ausblenden, Knöpfe,Animation,Hintergründe,Stile,Design,Themes,Menü-Zwischenspeicher, K-Menü,Zwischenspeicher,Lesezeichen,Zuletzt geöffnete Dateien, Schnellanzeiger,Menüs,Symbole,Icons,Kacheln,Applets,Miniprogramme, Java-Miniprogramme,Hervorhebung,Anfasser,Sicherheitsstufen,Zoom für Symbole
-Keywords[el]=kicker,πίνακας,kpanel,γραμμή εργασιών,γραμμή έναρξης,γραμμή εκκίνησης,τοποθεσία,μέγεθος,αυτόματη απόκρυψη,απόκρυψη,κουμπιά,εφέ κίνησης,φόντο,θέματα,λανθάνουσα μνήμη μενού,λανθάνουσα μνήμη,κρυφό, K-Μενού,σελιδοδείκτες,πρόσφατα έγγραφα,γρήγορος εξερευνητής,μενού εξερευνητή,μενού,εικονίδια,tiles,μικροεφαρμογές,έναρξη,τονισμός,χειριστήρια, μεγέθυνση εικονιδίων
+Keywords[el]=kicker,πίνακας,kpanel,γραμμή εργασιών,γραμμή έναρξης,γραμμή εκκίνησης,τοποθεσία,μέγεθος,αυτόματη απόκρυψη,απόκρυψη,κουμπιά,εφέ κίνησης,φόντο,θέματα,λανθάνουσα μνήμη μενού,λανθάνουσα μνήμη,κρυφό, K-Μενού,σελιδοδείκτες,πρόσφατα έγγραφα,γρήγορος εξερευνητής,μενού εξερευνητή,μενού,εικονίδια,tiles,εφαρμογίδια,έναρξη,τονισμός,χειριστήρια, μεγέθυνση εικονιδίων
Keywords[eo]=lanĉilo,panelo,tasklistelo,situo,grandeco,aŭtokaŝo,kaŝo,butono,fono,etoso,menubufro,K-Menuo,legosigno,lasta dokumento,rapidrigardilo,rigardmenuo,piktogramo,kahelo,aplikaĵo,lanĉo,emfazo,teniloj,pligrandigo,fidindaj aplikaĵetoj,sekurecnivelo
Keywords[es]=kicker,panel,kpanel,barra de tareas,barra de inicio,barra de lanzamiento,dirección,tamaño,auto ocultar,ocultar,botones,animación,fondo,temas,caché de menú,caché,oculto,Menú K,marcadores,documentos recientes,navegador rápido,menú navegador,menú,iconos,mosaicos,miniaplicaciones,arranque,resaltado,asas,iconos ampliados
Keywords[et]=kicker,paneel,kpanel,tegumiriba,käivitusriba,asukoht,suurus,terminal,automaatne peitmine,peitmine,nupud,animatsioon,taust,teemad,menüü vahemälu,vahemälu,peidetud,K-menüü,järjehoidjad,viimati kasutatud dokumendid, kiirbrauser,lehitsemise menüü,menüü,ikoonid,apletid,käivitamine,esiletõstmine,piirded,ikoonide suurendamine,usaldusväärsed apletid,turvatase
diff --git a/kcontrol/kicker/kicker_config_menus.desktop b/kcontrol/kicker/kicker_config_menus.desktop
index 3dbb52d48..b0bd513e1 100644
--- a/kcontrol/kicker/kicker_config_menus.desktop
+++ b/kcontrol/kicker/kicker_config_menus.desktop
@@ -147,7 +147,7 @@ Keywords[csb]=kicker,panel,kpanel,lëstëw zadaniów,sztartowô lëstëw,lëstë
Keywords[cy]=ciciwr,kicker,panel,kpanel,bar tasgau,bar cychwyn,bar lansio,lleoliad,maint,awto-guddio,hunan-guddio,cuddio,botymau,animeiddiad,cefndir,themâu,storfa dewislen, storfa,cache,celc,cudd,K-Menu,nodau tudalen,dogfenni diweddar,porydd cyflym,dewislen porydd,dewislen,eiconau,teiliau,rhaglenigion,ymcychwyn,amlygu,carnau,eiconau chwyddo
Keywords[da]=kicker,panel,kpanel,opgavelinje,startlinje,sted,størrelse,autogem,gem,knapper,animering,baggrund,temaer,menucache,cache,skjult,K-Menu,bogmærker,nylige dokumenter,hurtigsøger,søgemenu,menu,ikoner,fliser,panelprogrammer,opstart,markér,håndterer,ikoner
Keywords[de]=Kicker,Panel,Taskbar,Kontrollleiste,Startleiste,Klickstartleiste,Fensterleiste,Autom. ausblenden,Ausblenden, Knöpfe,Animation,Hintergründe,Stile,Design,Themes,Menü-Zwischenspeicher, K-Menü,Zwischenspeicher,Lesezeichen,Zuletzt geöffnete Dateien, Schnellanzeiger,Menüs,Symbole,Icons,Kacheln,Applets,Miniprogramme, Java-Miniprogramme,Hervorhebung,Anfasser,Sicherheitsstufen,Zoom für Symbole
-Keywords[el]=kicker,πίνακας,kpanel,γραμμή εργασιών,γραμμή έναρξης,γραμμή εκκίνησης,τοποθεσία,μέγεθος,αυτόματη απόκρυψη,απόκρυψη,κουμπιά,εφέ κίνησης,φόντο,θέματα,λανθάνουσα μνήμη μενού,λανθάνουσα μνήμη,κρυφό, K-Μενού,σελιδοδείκτες,πρόσφατα έγγραφα,γρήγορος εξερευνητής,μενού εξερευνητή,μενού,εικονίδια,tiles,μικροεφαρμογές,έναρξη,τονισμός,χειριστήρια, μεγέθυνση εικονιδίων
+Keywords[el]=kicker,πίνακας,kpanel,γραμμή εργασιών,γραμμή έναρξης,γραμμή εκκίνησης,τοποθεσία,μέγεθος,αυτόματη απόκρυψη,απόκρυψη,κουμπιά,εφέ κίνησης,φόντο,θέματα,λανθάνουσα μνήμη μενού,λανθάνουσα μνήμη,κρυφό, K-Μενού,σελιδοδείκτες,πρόσφατα έγγραφα,γρήγορος εξερευνητής,μενού εξερευνητή,μενού,εικονίδια,tiles,εφαρμογίδια,έναρξη,τονισμός,χειριστήρια, μεγέθυνση εικονιδίων
Keywords[eo]=lanĉilo,panelo,tasklistelo,situo,grandeco,aŭtokaŝo,kaŝo,butono,fono,etoso,menubufro,K-Menuo,legosigno,lasta dokumento,rapidrigardilo,rigardmenuo,piktogramo,kahelo,aplikaĵo,lanĉo,emfazo,teniloj,pligrandigo,fidindaj aplikaĵetoj,sekurecnivelo
Keywords[es]=kicker,panel,kpanel,barra de tareas,barra de inicio,barra de lanzamiento,dirección,tamaño,auto ocultar,ocultar,botones,animación,fondo,temas,caché de menú,caché,oculto,Menú K,marcadores,documentos recientes,navegador rápido,menú navegador,menú,iconos,mosaicos,miniaplicaciones,arranque,resaltado,asas,iconos ampliados
Keywords[et]=kicker,paneel,kpanel,tegumiriba,käivitusriba,asukoht,suurus,terminal,automaatne peitmine,peitmine,nupud,animatsioon,taust,teemad,menüü vahemälu,vahemälu,peidetud,K-menüü,järjehoidjad,viimati kasutatud dokumendid, kiirbrauser,lehitsemise menüü,menüü,ikoonid,apletid,käivitamine,esiletõstmine,piirded,ikoonide suurendamine,usaldusväärsed apletid,turvatase
diff --git a/kcontrol/kicker/menutab.ui b/kcontrol/kicker/menutab.ui
index f5e0ced05..7d3a3d460 100644
--- a/kcontrol/kicker/menutab.ui
+++ b/kcontrol/kicker/menutab.ui
@@ -8,8 +8,8 @@
0
0
- 410
- 437
+ 923
+ 649
@@ -19,6 +19,59 @@
0
+
+
+ layout5
+
+
+
+ unnamed
+
+
+
+ textLabel1
+
+
+ Start menu style:
+
+
+ comboMenuStyle
+
+
+
+ -
+
+ Kickoff
+
+
+ -
+
+ Trinity Classic
+
+
+
+ m_comboMenuStyle
+
+
+
+
+ spacer4
+
+
+ Horizontal
+
+
+ Expanding
+
+
+
+ 40
+ 20
+
+
+
+
+
m_kmenuGroup
@@ -38,6 +91,14 @@
unnamed
+
+
+ m_openOnHover
+
+
+ Open menu on mouse hover
+
+
kcfg_MenuEntryFormat
@@ -649,6 +710,8 @@
+
+
m_formatSimple
m_formatNameDesc
@@ -672,8 +735,5 @@
klistview.h
knuminput.h
- knuminput.h
- knuminput.h
- knuminput.h
diff --git a/kcontrol/kicker/menutab_impl.cpp b/kcontrol/kicker/menutab_impl.cpp
index 1d1053af8..b85db9fc7 100644
--- a/kcontrol/kicker/menutab_impl.cpp
+++ b/kcontrol/kicker/menutab_impl.cpp
@@ -16,12 +16,16 @@
*/
#include
+#include
#include
#include
#include
#include
#include
+#include
+#include
+#include
#include
#include
#include
@@ -148,12 +152,47 @@ void MenuTab::load( bool useDefaults )
}
}
+ c->setGroup("General");
+ m_comboMenuStyle->setCurrentItem( c->readBoolEntry("LegacyKMenu", true) ? 1 : 0 );
+ m_openOnHover->setChecked( c->readBoolEntry("OpenOnHover", true) );
+ menuStyleChanged();
+
+ connect(m_comboMenuStyle, TQT_SIGNAL(activated(int)), TQT_SIGNAL(changed()));
+ connect(m_comboMenuStyle, TQT_SIGNAL(activated(int)), TQT_SLOT(menuStyleChanged()));
+ connect(m_openOnHover, TQT_SIGNAL(clicked()), TQT_SIGNAL(changed()));
+
m_showFrequent->setChecked(true);
if ( useDefaults )
emit changed();
}
+void MenuTab::menuStyleChanged()
+{
+ if (m_comboMenuStyle->currentItem()==1) {
+ m_openOnHover->setEnabled(false);
+ m_subMenus->setEnabled(true);
+ kcfg_UseSidePixmap->setEnabled(true);
+ kcfg_MenuEntryFormat->setEnabled(true);
+ kcfg_RecentVsOften->setEnabled(true);
+ m_showFrequent->setEnabled(true);
+ kcfg_UseSearchBar->setEnabled(true);
+ kcfg_MaxEntries2->setEnabled(true);
+ maxrecentdocs->setEnabled(true);
+ }
+ else {
+ m_openOnHover->setEnabled(true);
+ m_subMenus->setEnabled(false);
+ kcfg_UseSidePixmap->setEnabled(false);
+ kcfg_MenuEntryFormat->setEnabled(false);
+ kcfg_RecentVsOften->setEnabled(false);
+ m_showFrequent->setEnabled(false);
+ kcfg_UseSearchBar->setEnabled(false);
+ kcfg_MaxEntries2->setEnabled(false);
+ maxrecentdocs->setEnabled(false);
+ }
+}
+
void MenuTab::save()
{
KSharedConfig::Ptr c = KSharedConfig::openConfig(KickerConfig::the()->configName());
@@ -179,9 +218,18 @@ void MenuTab::save()
}
}
c->writeEntry("Extensions", ext);
+ c->setGroup("General");
+ bool kmenusetting = m_comboMenuStyle->currentItem()==1;
+ bool oldkmenusetting = c->readBoolEntry("LegacyKMenu", true);
+
+ c->writeEntry("LegacyKMenu", kmenusetting);
+ c->writeEntry("OpenOnHover", m_openOnHover->isChecked());
c->sync();
+ if (kmenusetting != oldkmenusetting)
+ DCOPRef ("kicker", "default").call("restart()");
+
// Save KMenu settings
c->setGroup("KMenu");
c->writeEntry("CustomIcon", m_kmenu_icon);
@@ -195,7 +243,7 @@ void MenuTab::save()
config->sync();
if (m_kmenu_button_changed == true) {
- system("dcop kicker kicker restart &");
+ DCOPRef ("kicker", "default").call("restart()");
}
}
diff --git a/kcontrol/kicker/menutab_impl.h b/kcontrol/kicker/menutab_impl.h
index 877e47ffe..3ef197f09 100644
--- a/kcontrol/kicker/menutab_impl.h
+++ b/kcontrol/kicker/menutab_impl.h
@@ -65,6 +65,7 @@ signals:
public slots:
void launchMenuEditor();
+ void menuStyleChanged();
void launchIconEditor();
void kmenuChanged();
diff --git a/kicker/applets/clock/clock.cpp b/kicker/applets/clock/clock.cpp
index 7bc46afa4..26f1ae4c0 100644
--- a/kicker/applets/clock/clock.cpp
+++ b/kicker/applets/clock/clock.cpp
@@ -901,8 +901,8 @@ ClockApplet::ClockApplet(const TQString& configFile, Type t, int actions,
_calendar(0),
_disableCalendar(false),
_clock(0),
- _timer(new TQTimer(this)),
- m_layoutTimer(new TQTimer(this)),
+ _timer(new TQTimer(this, "ClockApplet::_timer")),
+ m_layoutTimer(new TQTimer(this, "m_layoutTimer")),
m_layoutDelay(0),
m_followBackgroundSetting(true),
m_dateFollowBackgroundSetting(true),
diff --git a/kicker/applets/launcher/quicklauncher.cpp b/kicker/applets/launcher/quicklauncher.cpp
index 557ea4cd3..a278b39c9 100644
--- a/kicker/applets/launcher/quicklauncher.cpp
+++ b/kicker/applets/launcher/quicklauncher.cpp
@@ -110,7 +110,7 @@ QuickLauncher::QuickLauncher(const TQString& configFile, Type type, int actions,
m_configAction = new KAction(i18n("Configure Quicklauncher..."), "configure", KShortcut(),
this, TQT_SLOT(slotConfigure()), this);
- m_saveTimer = new TQTimer(this);
+ m_saveTimer = new TQTimer(this, "m_saveTimer");
connect(m_saveTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(saveConfig()));
m_popularity = new PopularityStatistics();
diff --git a/kicker/applets/media/mediumbutton.cpp b/kicker/applets/media/mediumbutton.cpp
index 5be2acbab..0fae43441 100644
--- a/kicker/applets/media/mediumbutton.cpp
+++ b/kicker/applets/media/mediumbutton.cpp
@@ -45,7 +45,8 @@
#include
MediumButton::MediumButton(TQWidget *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, TQT_SLOT(slotPaste()),
&mActions, "pasteto");
@@ -74,9 +75,9 @@ MediumButton::MediumButton(TQWidget *parent, const KFileItem &fileItem)
MediumButton::~MediumButton()
{
- TQPopupMenu *menu = popup();
- setPopup(0);
- delete menu;
+ TQPopupMenu *menu = static_cast(popup());
+ setPopup(0);
+ delete menu;
}
const KFileItem &MediumButton::fileItem() const
@@ -94,29 +95,29 @@ void MediumButton::setFileItem(const KFileItem &fileItem)
void MediumButton::initPopup()
{
- TQPopupMenu *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;
+ TQPopupMenu *old_popup = static_cast(popup());
+
+ KFileItemList items;
+ items.append(&mFileItem);
+
+ KonqPopupMenu::KonqPopupFlags kpf =
+ KonqPopupMenu::ShowProperties
+ | KonqPopupMenu::ShowNewWindow;
+
+ KParts::BrowserExtension::PopupFlags bef =
+ KParts::BrowserExtension::DefaultPopupItems;
+
+ KonqPopupMenu *new_popup = new KonqPopupMenu(0L, items,
+ KURL("media:/"), mActions, 0L,
+ this, kpf, bef);
+ KPopupTitle *title = new KPopupTitle(new_popup);
+ title->setTitle(mFileItem.text());
+
+ new_popup->insertItem(title, -1, 0);
+
+ setPopup(new_popup);
+
+ if (old_popup!=0L) delete old_popup;
}
void MediumButton::refreshType()
diff --git a/kicker/applets/minipager/pagerbutton.cpp b/kicker/applets/minipager/pagerbutton.cpp
index c56afca38..10a5aa8c9 100644
--- a/kicker/applets/minipager/pagerbutton.cpp
+++ b/kicker/applets/minipager/pagerbutton.cpp
@@ -70,6 +70,8 @@ KMiniPagerButton::KMiniPagerButton(int desk, bool useViewPorts, const TQPoint& v
m_bgPixmap(0),
m_isCommon(false),
m_currentWindow(0),
+ m_updateCompressor(0, "KMiniPagerButton::updateCompressor"),
+ m_dragSwitchTimer(0, "KMiniPagerButton::dragSwitchTimer"),
m_inside(false)
{
setToggleButton(true);
diff --git a/kicker/applets/naughty/NaughtyProcessMonitor.cpp b/kicker/applets/naughty/NaughtyProcessMonitor.cpp
index 37cba7a37..6228cfba1 100644
--- a/kicker/applets/naughty/NaughtyProcessMonitor.cpp
+++ b/kicker/applets/naughty/NaughtyProcessMonitor.cpp
@@ -94,7 +94,7 @@ NaughtyProcessMonitor::NaughtyProcessMonitor
d = new NaughtyProcessMonitorPrivate;
d->interval_ = interval * 1000;
d->triggerLevel_ = triggerLevel;
- d->timer_ = new TQTimer(this);
+ d->timer_ = new TQTimer(this, "NaughtyProcessMonitorPrivate::timer");
connect(d->timer_, TQT_SIGNAL(timeout()), this, TQT_SLOT(slotTimeout()));
}
diff --git a/kicker/applets/systemtray/systemtrayapplet.cpp b/kicker/applets/systemtray/systemtrayapplet.cpp
index 51bf2b9d8..ad44b640f 100644
--- a/kicker/applets/systemtray/systemtrayapplet.cpp
+++ b/kicker/applets/systemtray/systemtrayapplet.cpp
@@ -401,7 +401,7 @@ void SystemTrayApplet::showExpandButton(bool show)
connect(m_expandButton, TQT_SIGNAL(clicked()),
this, TQT_SLOT(toggleExpanded()));
- m_autoRetractTimer = new TQTimer(this);
+ m_autoRetractTimer = new TQTimer(this, "m_autoRetractTimer");
connect(m_autoRetractTimer, TQT_SIGNAL(timeout()),
this, TQT_SLOT(checkAutoRetract()));
}
diff --git a/kicker/applets/trash/trashbutton.cpp b/kicker/applets/trash/trashbutton.cpp
index eb036c119..19e6be02b 100644
--- a/kicker/applets/trash/trashbutton.cpp
+++ b/kicker/applets/trash/trashbutton.cpp
@@ -78,7 +78,7 @@ void TrashButton::setItemCount(int count)
void TrashButton::initPopup()
{
- TQPopupMenu *old_popup = popup();
+ TQPopupMenu *old_popup = static_cast(popup());
KFileItemList items;
items.append(&mFileItem);
diff --git a/kicker/configure.in.in b/kicker/configure.in.in
new file mode 100644
index 000000000..4da44a4a8
--- /dev/null
+++ b/kicker/configure.in.in
@@ -0,0 +1,78 @@
+dnl Check for pkg-config
+AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
+
+if test "$PKG_CONFIG" = "no"; then
+ AC_MSG_ERROR([
+This package requires pkg-config.
+])
+fi
+
+dnl Check for Glib-2.0
+# GLIB_CFLAGS: cflags for compiling glib dependant sources
+# GLIB_LIBADD: glib libraries (-l options)
+# GLIB_LDFLAGS: flags containing path to glib libraries (-L options)
+
+GLIB_PACKAGES="gmodule-2.0 gthread-2.0"
+GLIB_VERSION="1.3.3"
+AC_MSG_CHECKING(for GLib-2.0 (at least $GLIB_VERSION))
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.15 ; then
+ if $PKG_CONFIG --atleast-version $GLIB_VERSION $GLIB_PACKAGES >/dev/null 2>&1 ; then
+ GLIB_CFLAGS="`$PKG_CONFIG --cflags $GLIB_PACKAGES`"
+ GLIB_LIBADD="`$PKG_CONFIG --libs-only-l --libs-only-other $GLIB_PACKAGES`"
+ GLIB_LDFLAGS="`$PKG_CONFIG --libs-only-L $GLIB_PACKAGES`"
+ AC_MSG_RESULT(yes)
+ fi
+else
+ if $PKG_CONFIG --atleast-version $GLIB_VERSION $GLIB_PACKAGES >/dev/null 2>&1 ; then
+ GLIB_CFLAGS="`$PKG_CONFIG --cflags $GLIB_PACKAGES`"
+ GLIB_LIBADD="`$PKG_CONFIG --libs-only-l $GLIB_PACKAGES`"
+ GLIB_LDFLAGS="`$PKG_CONFIG --libs-only-L $GLIB_PACKAGES`"
+ AC_MSG_RESULT(yes)
+ AC_MSG_WARN([you may need to run make LDFLAGS=-pthread to compile arts])
+ fi
+fi
+
+if test -z "$GLIB_LIBADD"; then
+ AC_MSG_RESULT(not installed)
+ DO_NOT_COMPILE="$DO_NOT_COMPILE kerry gmcop"
+fi
+
+AC_SUBST(GLIB_CFLAGS)
+AC_SUBST(GLIB_LIBADD)
+AC_SUBST(GLIB_LDFLAGS)
+
+dnl Check for libbeagle 0.2.0
+# LIBBEAGLE_CFLAGS: cflags for compiling libbeagle dependant sources
+# LIBBEAGLE_LIBADD: libbeagle libraries (-l options)
+# LIBBEAGLE_LDFLAGS: flags containing path to libbeagle libraries (-L options)
+
+LIBBEAGLE_PACKAGES="libbeagle-0.0"
+LIBBEAGLE_VERSION="0.2.4"
+AC_MSG_CHECKING(for libbeagle-0.2.4 (at least $LIBBEAGLE_VERSION))
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.15 ; then
+ if $PKG_CONFIG --atleast-version $LIBBEAGLE_VERSION $LIBBEAGLE_PACKAGES >/dev/null 2>&1 ; then
+ LIBBEAGLE_CFLAGS="`$PKG_CONFIG --cflags $LIBBEAGLE_PACKAGES`"
+ LIBBEAGLE_LIBADD="`$PKG_CONFIG --libs-only-l --libs-only-other $LIBBEAGLE_PACKAGES`"
+ LIBBEAGLE_LDFLAGS="`$PKG_CONFIG --libs-only-L $LIBBEAGLE_PACKAGES`"
+ AC_MSG_RESULT(yes)
+ fi
+else
+ if $PKG_CONFIG --atleast-version $LIBBEAGLE_VERSION $LIBBEAGLE_PACKAGES >/dev/null 2>&1 ; then
+ LIBBEAGLE_CFLAGS="`$PKG_CONFIG --cflags $LIBBEAGLE_PACKAGES`"
+ LIBBEAGLE_LIBADD="`$PKG_CONFIG --libs-only-l $LIBBEAGLE_PACKAGES`"
+ LIBBEAGLE_LDFLAGS="`$PKG_CONFIG --libs-only-L $LIBBEAGLE_PACKAGES`"
+ AC_MSG_RESULT(yes)
+ AC_MSG_WARN([you may need to run make LDFLAGS=-pthread to compile arts])
+ fi
+fi
+
+if test -z "$LIBBEAGLE_LIBADD"; then
+ AC_MSG_RESULT(not installed)
+ DO_NOT_COMPILE="$DO_NOT_COMPILE kerry gmcop"
+fi
+
+AC_SUBST(LIBBEAGLE_CFLAGS)
+AC_SUBST(LIBBEAGLE_LIBADD)
+AC_SUBST(LIBBEAGLE_LDFLAGS)
diff --git a/kicker/data/Makefile.am b/kicker/data/Makefile.am
index 41d9598ed..53e72912e 100644
--- a/kicker/data/Makefile.am
+++ b/kicker/data/Makefile.am
@@ -1 +1 @@
-SUBDIRS = icons tiles app_start_anim wallpaper kmenu_side
+SUBDIRS = icons tiles app_start_anim wallpaper kmenu_side kickoff
diff --git a/kicker/data/kickoff/Makefile.am b/kicker/data/kickoff/Makefile.am
new file mode 100644
index 000000000..20ac737ff
--- /dev/null
+++ b/kicker/data/kickoff/Makefile.am
@@ -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
diff --git a/kicker/data/kickoff/kmenu_active.png b/kicker/data/kickoff/kmenu_active.png
index fa5ae4de1..7a3d6b08f 100644
Binary files a/kicker/data/kickoff/kmenu_active.png and b/kicker/data/kickoff/kmenu_active.png differ
diff --git a/kicker/data/kickoff/kmenu_basic.mng b/kicker/data/kickoff/kmenu_basic.mng
index 4cea61fff..d3423d867 100644
Binary files a/kicker/data/kickoff/kmenu_basic.mng and b/kicker/data/kickoff/kmenu_basic.mng differ
diff --git a/kicker/data/kickoff/kmenu_flipped.mng b/kicker/data/kickoff/kmenu_flipped.mng
index 2b78b4007..d3423d867 100644
Binary files a/kicker/data/kickoff/kmenu_flipped.mng and b/kicker/data/kickoff/kmenu_flipped.mng differ
diff --git a/kicker/data/kickoff/kmenu_vertical.mng b/kicker/data/kickoff/kmenu_vertical.mng
index 9cd3aac2b..7f7047d11 100644
Binary files a/kicker/data/kickoff/kmenu_vertical.mng and b/kicker/data/kickoff/kmenu_vertical.mng differ
diff --git a/kicker/data/kmenu_side/Makefile.am b/kicker/data/kmenu_side/Makefile.am
index ee19c9a20..2d3e00932 100644
--- a/kicker/data/kmenu_side/Makefile.am
+++ b/kicker/data/kmenu_side/Makefile.am
@@ -1,6 +1,5 @@
-kicker_kmenuside_pics_data_DATA = kside.png kside_tile.png
-
-kicker_kmenuside_pics_datadir = $(kde_datadir)/kicker/pics/
+kicker_kmenuside_pics_data_DATA = kside.png kside_tile.png
+kicker_kmenuside_pics_datadir = $(kde_datadir)/kicker/pics
EXTRA_DIST = $(kicker_kmenuside_pics_data_DATA)
diff --git a/kicker/extensions/kasbar/kasbar.cpp b/kicker/extensions/kasbar/kasbar.cpp
index 06bf3c24f..bf2b64ba3 100644
--- a/kicker/extensions/kasbar/kasbar.cpp
+++ b/kicker/extensions/kasbar/kasbar.cpp
@@ -719,7 +719,7 @@ void KasBar::addTestItems()
i->setText( "Animated" );
i->setIcon( KGlobal::iconLoader()->loadIcon( "icons", KIcon::NoGroup, KIcon::SizeMedium ) );
i->setAnimation( resources()->startupAnimation() );
- TQTimer *aniTimer = new TQTimer( i );
+ TQTimer *aniTimer = new TQTimer( i, "aniTimer" );
connect( aniTimer, TQT_SIGNAL( timeout() ), i, TQT_SLOT( advanceAnimation() ) );
aniTimer->start( 100 );
i->setShowAnimation( true );
diff --git a/kicker/extensions/kasbar/kasclockitem.cpp b/kicker/extensions/kasbar/kasclockitem.cpp
index 386a7922d..f025af857 100644
--- a/kicker/extensions/kasbar/kasclockitem.cpp
+++ b/kicker/extensions/kasbar/kasclockitem.cpp
@@ -38,7 +38,7 @@ KasClockItem::KasClockItem( KasBar *parent )
{
setCustomPopup( true );
- TQTimer *t = new TQTimer( this );
+ TQTimer *t = new TQTimer( this, "t" );
connect( t, TQT_SIGNAL( timeout() ), TQT_SLOT( updateTime() ) );
t->start( 1000 );
diff --git a/kicker/extensions/kasbar/kasloaditem.cpp b/kicker/extensions/kasbar/kasloaditem.cpp
index 2d33a068d..7b6939760 100644
--- a/kicker/extensions/kasbar/kasloaditem.cpp
+++ b/kicker/extensions/kasbar/kasloaditem.cpp
@@ -33,7 +33,7 @@
KasLoadItem::KasLoadItem( KasBar *parent )
: KasItem( parent )
{
- TQTimer *t = new TQTimer( this );
+ TQTimer *t = new TQTimer( this, "KasLoadItem::t" );
connect( t, TQT_SIGNAL( timeout() ), TQT_SLOT( updateDisplay() ) );
t->start( 1000 );
updateDisplay();
diff --git a/kicker/extensions/kasbar/kasstartupitem.cpp b/kicker/extensions/kasbar/kasstartupitem.cpp
index 53d823430..4d2ac3b00 100644
--- a/kicker/extensions/kasbar/kasstartupitem.cpp
+++ b/kicker/extensions/kasbar/kasstartupitem.cpp
@@ -79,7 +79,7 @@ KasStartupItem::KasStartupItem( KasBar *parent, Startup::Ptr startup )
setShowFrame( false );
setAnimation( resources()->startupAnimation() );
- aniTimer = new TQTimer( this );
+ aniTimer = new TQTimer( this, "aniTimer" );
connect( aniTimer, TQT_SIGNAL( timeout() ), TQT_SLOT( aniTimerFired() ) );
aniTimer->start( 100 );
}
diff --git a/kicker/kicker/Makefile.am b/kicker/kicker/Makefile.am
index 857ac9cff..9a89a0ac0 100644
--- a/kicker/kicker/Makefile.am
+++ b/kicker/kicker/Makefile.am
@@ -1,6 +1,7 @@
INCLUDES = $(all_includes)
-SUBDIRS = core ui buttons .
+# SUBDIRS = core interfaces ui buttons plugins .
+SUBDIRS = core interfaces ui buttons .
bin_PROGRAMS =
lib_LTLIBRARIES =
@@ -9,7 +10,7 @@ kdeinit_LTLIBRARIES = kicker.la
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)
diff --git a/kicker/kicker/buttons/Makefile.am b/kicker/kicker/buttons/Makefile.am
index 2ba4d20c6..1ec3d42d6 100644
--- a/kicker/kicker/buttons/Makefile.am
+++ b/kicker/kicker/buttons/Makefile.am
@@ -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) $(LIBBEAGLE_CFLAGS) $(GLIB_CFLAGS)
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
diff --git a/kicker/kicker/buttons/browserbutton.cpp b/kicker/kicker/buttons/browserbutton.cpp
index 950882696..2e2cb5a2d 100644
--- a/kicker/kicker/buttons/browserbutton.cpp
+++ b/kicker/kicker/buttons/browserbutton.cpp
@@ -65,7 +65,7 @@ void BrowserButton::initialize( const TQString& icon, const TQString& path )
topMenu = new PanelBrowserMenu( path );
setPopup(topMenu);
- _menuTimer = new TQTimer( this );
+ _menuTimer = new TQTimer( this, "_menuTimer" );
connect( _menuTimer, TQT_SIGNAL(timeout()), TQT_SLOT(slotDelayedPopup()) );
TQToolTip::add(this, i18n("Browse: %1").arg(path));
diff --git a/kicker/kicker/buttons/kbutton.cpp b/kicker/kicker/buttons/kbutton.cpp
index 73454b99f..d39346edb 100644
--- a/kicker/kicker/buttons/kbutton.cpp
+++ b/kicker/kicker/buttons/kbutton.cpp
@@ -33,6 +33,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "menumanager.h"
#include "k_mnu.h"
+#include "k_mnu_stub.h"
#include "kbutton.h"
#include "kbutton.moc"
@@ -43,7 +44,7 @@ KButton::KButton( TQWidget* parent )
TQToolTip::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");
diff --git a/kicker/kicker/buttons/knewbutton.cpp b/kicker/kicker/buttons/knewbutton.cpp
new file mode 100644
index 000000000..9c9f438ac
--- /dev/null
+++ b/kicker/kicker/buttons/knewbutton.cpp
@@ -0,0 +1,455 @@
+/*****************************************************************
+
+Copyright (c) 2006 Stephan Binner
+ Stephan Kulow
+ Dirk Mueller
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+#include "kickerSettings.h"
+
+#include "config.h"
+#include "global.h"
+
+#include "menumanager.h"
+#include "k_mnu_stub.h"
+#include "k_new_mnu.h"
+
+#include "knewbutton.h"
+#include "knewbutton.moc"
+
+KNewButton *KNewButton::m_self = 0;
+
+KNewButton::KNewButton( TQWidget* 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 TQMovie(locate("data", "kicker/pics/kmenu_basic.mng"));
+ m_movie->connectUpdate(this, TQT_SLOT(updateMovie()));
+ m_movie->connectStatus(this, TQT_SLOT(slotStatus(int)));
+ m_movie->connectResize(this, TQT_SLOT(slotSetSize(const TQSize&)));
+
+ TQApplication::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 == TQMovie::EndOfLoop)
+ slotStopAnimation();
+}
+
+TQColor KNewButton::borderColor() const
+{
+ TQImage 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()) {
+ TQTimer::singleShot(500,this,TQT_SLOT(slotExecMenu()));
+ KickerSettings::setFirstRun(false);
+ KickerSettings::writeConfig();
+ }
+}
+
+void KNewButton::updateMovie()
+{
+ m_oldPos = TQPoint( -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 TQMovie(locate("data", "kicker/pics/kmenu_vertical.mng"));
+ break;
+ case KPanelApplet::Right:
+ setIconAlignment((Qt::AlignmentFlags)(AlignTop|AlignRight));
+ m_movie = new TQMovie(locate("data", "kicker/pics/kmenu_vertical.mng"));
+ break;
+ case KPanelApplet::Up:
+ setIconAlignment((Qt::AlignmentFlags)(AlignTop|AlignHCenter));
+ m_movie = new TQMovie(locate("data", "kicker/pics/kmenu_basic.mng"));
+ break;
+ case KPanelApplet::Down:
+ setIconAlignment((Qt::AlignmentFlags)(AlignBottom|AlignHCenter));
+ m_movie = new TQMovie(locate("data", "kicker/pics/kmenu_flipped.mng"));
+ }
+
+ m_movie->connectUpdate(this, TQT_SLOT(updateMovie()));
+ m_movie->connectStatus(this, TQT_SLOT(slotStatus(int)));
+ m_movie->connectResize(this, TQT_SLOT(slotSetSize(const TQSize&)));
+}
+
+void KNewButton::slotSetSize(const TQSize& s)
+{
+ m_iconSize = s;
+}
+
+double KNewButton::buttonScaleFactor(const TQSize& 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(TQSize(m_iconSize.width(), height));
+
+ if (!m_movie->running() && height != m_active_pixmap.height())
+ {
+ KNewButton* that = const_cast(this);
+ TQTimer::singleShot(0, that, TQT_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(TQSize(width, m_iconSize.height()));
+ if (!m_movie->running() && width != m_active_pixmap.width())
+ {
+ KNewButton* that = const_cast(this);
+ TQTimer::singleShot(0, that, TQT_SLOT(slotStopAnimation()));
+ }
+ return r;
+}
+
+bool KNewButton::eventFilter(TQObject *o, TQEvent *e)
+{
+ if (e->type() == TQEvent::MouseButtonRelease ||
+ e->type() == TQEvent::MouseButtonPress ||
+ e->type() == TQEvent::MouseButtonDblClick )
+ {
+ TQMouseEvent *me = static_cast(e);
+ if (rect().contains(mapFromGlobal(me->globalPos())))
+ {
+ if (m_pressedDuringPopup && m_popup && m_openTimer != -1
+ && (me->button() & Qt::LeftButton) )
+ return true;
+ }
+ }
+
+ if (KickerSettings::kickoffDrawGeekoEye() && e->type() == TQEvent::MouseMove)
+ {
+ TQMouseEvent *me = static_cast(e);
+ if ((me->state() & MouseButtonMask) == NoButton)
+ drawEye();
+ }
+
+ return KButton::eventFilter(o, e);
+}
+
+void KNewButton::drawEye()
+{
+#define eye_x 62
+#define eye_y 13
+ TQPoint mouse = TQCursor::pos();
+ TQPoint me = mapToGlobal(TQPoint(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));
+
+ TQPoint newpos(eye_x+dx,eye_y+dy);
+ if (newpos!=m_oldPos) {
+ m_oldPos = newpos;
+ TQPixmap 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()) {
+ TQPainter p(&pixmap);
+ p.setPen(white);
+ p.setBrush(white);
+ // p.setPen(TQColor(110,185,55));
+ p.drawRect(eye_x+dx, eye_y+dy, 2, 2);
+ p. end();
+ }
+ }
+
+ TQWMatrix 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(TQEvent* e)
+{
+ KButton::enterEvent(e);
+
+ TQSize s(size());
+ s *= 0.25;
+ s = s.expandedTo(TQSize(6,6));
+
+ switch (popupDirection()) {
+ case KPanelApplet::Left:
+ m_sloppyRegion = TQRect(rect().topRight() - TQPoint(s.width()-1, 0), s);
+ break;
+ case KPanelApplet::Right:
+ m_sloppyRegion = TQRect(rect().topLeft(), s);
+ break;
+ case KPanelApplet::Up:
+ m_sloppyRegion = TQRect(rect().bottomLeft() - TQPoint(0, s.height()-1), s);
+ break;
+ case KPanelApplet::Down:
+ m_sloppyRegion = TQRect(rect().topLeft(), s);
+ }
+
+ m_active = true;
+ m_movie->unpause();
+ m_movie->restart();
+}
+
+void KNewButton::rewindMovie()
+{
+ m_oldPos = TQPoint( -1, -1 );
+ m_movie->unpause();
+}
+
+void KNewButton::dragEnterEvent(TQDragEnterEvent* /*e*/)
+{
+ if (m_hoverTimer != -1)
+ killTimer(m_hoverTimer);
+
+ m_hoverTimer = startTimer(TQApplication::startDragTime());
+ m_mouseInside = true;
+ m_drag = true;
+}
+
+void KNewButton::dragLeaveEvent(TQDragLeaveEvent* /*e*/)
+{
+ m_mouseInside = false;
+ m_drag = false;
+}
+
+void KNewButton::leaveEvent(TQEvent* e)
+{
+ m_mouseInside = false;
+ if (m_hoverTimer != -1)
+ killTimer(m_hoverTimer);
+ m_hoverTimer = -1;
+
+ KButton::leaveEvent(e);
+}
+
+void KNewButton::mouseMoveEvent(TQMouseEvent* 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,TQApplication::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();
+ TQTimer::singleShot(200, this, TQT_SLOT(rewindMovie()));
+}
+
+const TQPixmap& KNewButton::labelIcon() const
+{
+ return m_active_pixmap;
+}
+
+void KNewButton::slotExecMenu()
+{
+ if (m_openTimer != -1)
+ killTimer(m_openTimer);
+
+ m_openTimer = startTimer(TQApplication::doubleClickInterval() * 3);
+
+ if (m_active)
+ {
+ m_active = false;
+ m_movie->pause();
+ m_movie->restart();
+ }
+
+ KButton::slotExecMenu();
+
+ assert(!KickerTip::tippingEnabled());
+ assert(dynamic_cast(m_popup));
+
+ disconnect(dynamic_cast(m_popup), TQT_SIGNAL(aboutToHide()), this,
+ TQT_SLOT(slotStopAnimation()));
+ connect(dynamic_cast(m_popup), TQT_SIGNAL(aboutToHide()),
+ TQT_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 TQApplication::isEffectEnabled()
+ useEffect = false; // too many TQt bugs to be useful
+ if (m_drag)
+ useEffect = false;
+
+ m_drag = false; // once is enough
+
+ if (useEffect)
+ {
+ switch (popupDirection()) {
+ case KPanelApplet::Left:
+ qScrollEffect(m_popup, QEffects::LeftScroll);
+ break;
+ case KPanelApplet::Up:
+ qScrollEffect(m_popup, QEffects::UpScroll);
+ break;
+ case KPanelApplet::Right:
+ qScrollEffect(m_popup, QEffects::RightScroll);
+ break;
+ case KPanelApplet::Down:
+ qScrollEffect(m_popup, QEffects::DownScroll);
+ break;
+ }
+ }
+ else
+ static_cast(m_popup)->show();
+}
+
+void KNewButton::timerEvent(TQTimerEvent* 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;
+ }
+}
diff --git a/kicker/kicker/buttons/knewbutton.h b/kicker/kicker/buttons/knewbutton.h
new file mode 100644
index 000000000..bcb8b8743
--- /dev/null
+++ b/kicker/kicker/buttons/knewbutton.h
@@ -0,0 +1,98 @@
+/*****************************************************************
+
+Copyright (c) 2006 Stephan Binner
+ Stephan Kulow
+ Dirk Mueller
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#ifndef __knewbutton_h__
+#define __knewbutton_h__
+
+#include "kbutton.h"
+
+#include
+#include
+
+/**
+ * Button that contains the PanelKMenu and client menu manager.
+ */
+class KNewButton : public KButton
+{
+ Q_OBJECT
+
+public:
+ KNewButton( TQWidget *parent );
+ ~KNewButton();
+
+ static KNewButton *self() { return m_self; }
+
+ void loadConfig( const KConfigGroup& config );
+
+ virtual const TQPixmap& labelIcon() const;
+
+ virtual int widthForHeight(int height) const;
+ virtual int preferredDimension(int panelDim) const;
+ virtual int heightForWidth(int width) const;
+
+ TQColor borderColor() const;
+
+ virtual void setPopupDirection(KPanelApplet::Direction d);
+
+private slots:
+ void slotStatus(int);
+ void slotSetSize(const TQSize&);
+ void slotStopAnimation();
+ void rewindMovie();
+ void updateMovie();
+
+protected:
+ virtual void show();
+ virtual void slotExecMenu();
+ virtual TQString tileName() { return "KMenu"; }
+ virtual TQString defaultIcon() const { return "go"; }
+
+ virtual void enterEvent(TQEvent* e);
+ virtual void leaveEvent(TQEvent* e);
+ virtual void mouseMoveEvent(TQMouseEvent* e);
+ virtual void dragEnterEvent(TQDragEnterEvent*);
+ virtual void dragLeaveEvent(TQDragLeaveEvent*);
+ virtual bool eventFilter(TQObject *, TQEvent *);
+ void timerEvent(TQTimerEvent*);
+
+private:
+ void drawEye();
+ double buttonScaleFactor(const TQSize& s) const;
+
+ TQMovie* m_movie;
+ TQPixmap m_active_pixmap;
+ TQPoint m_oldPos;
+ TQSize m_iconSize;
+ TQRect m_sloppyRegion;
+ int m_hoverTimer;
+ int m_openTimer;
+ bool m_active;
+ bool m_mouseInside;
+ bool m_drag;
+
+ static KNewButton *m_self;
+};
+
+#endif
diff --git a/kicker/kicker/core/Makefile.am b/kicker/kicker/core/Makefile.am
index 6986af604..25e7e733a 100644
--- a/kicker/kicker/core/Makefile.am
+++ b/kicker/kicker/core/Makefile.am
@@ -1,12 +1,14 @@
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) $(LIBBEAGLE_CFLAGS) $(GLIB_CFLAGS)
noinst_LTLIBRARIES = libkicker_core.la
+libkicker_core_la_COMPILE_FIRST = kmenubase.h
+
libkicker_core_la_SOURCES = extensionSettings.kcfgc \
main.cpp kicker.cpp kicker.skel \
- userrectsel.cpp containerarea.cpp \
+ userrectsel.cpp containerarea.cpp kmenubase.ui \
applethandle.cpp container_base.cpp container_button.cpp \
container_applet.cpp container_extension.cpp extensionmanager.cpp \
menumanager.cpp pluginmanager.cpp showdesktop.cpp \
diff --git a/kicker/kicker/core/applethandle.cpp b/kicker/kicker/core/applethandle.cpp
index 251cbc1bd..f5f398136 100644
--- a/kicker/kicker/core/applethandle.cpp
+++ b/kicker/kicker/core/applethandle.cpp
@@ -150,7 +150,7 @@ void AppletHandle::setFadeOutHandle(bool fadeOut)
{
if (!m_handleHoverTimer)
{
- m_handleHoverTimer = new TQTimer(this);
+ m_handleHoverTimer = new TQTimer(this, "m_handleHoverTimer");
connect(m_handleHoverTimer, TQT_SIGNAL(timeout()),
this, TQT_SLOT(checkHandleHover()));
m_applet->installEventFilter(this);
@@ -177,11 +177,7 @@ bool AppletHandle::eventFilter(TQObject *o, TQEvent *e)
m_drawHandle = true;
resetLayout();
- if (m_handleHoverTimer)
- {
- m_handleHoverTimer->start(250);
- }
- break;
+ break;
}
case TQEvent::Leave:
@@ -191,6 +187,11 @@ bool AppletHandle::eventFilter(TQObject *o, TQEvent *e)
break;
}
+ if (m_handleHoverTimer)
+ {
+ m_handleHoverTimer->start(250);
+ }
+
TQWidget* w = dynamic_cast(o);
bool nowDrawIt = false;
@@ -207,11 +208,6 @@ bool AppletHandle::eventFilter(TQObject *o, TQEvent *e)
if (nowDrawIt != m_drawHandle)
{
- if (m_handleHoverTimer)
- {
- m_handleHoverTimer->stop();
- }
-
m_drawHandle = nowDrawIt;
resetLayout();
}
@@ -297,6 +293,11 @@ void AppletHandle::toggleMenuButtonOff()
}
m_menuButton->setDown(false);
+
+ if (m_handleHoverTimer)
+ {
+ m_handleHoverTimer->start(250);
+ }
}
AppletHandleDrag::AppletHandleDrag(AppletHandle* parent)
diff --git a/kicker/kicker/core/container_button.cpp b/kicker/kicker/core/container_button.cpp
index 8ac39a47f..bb0249843 100644
--- a/kicker/kicker/core/container_button.cpp
+++ b/kicker/kicker/core/container_button.cpp
@@ -43,6 +43,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#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 @@ KMenuButtonContainer::KMenuButtonContainer(const KConfigGroup& config, TQPopupMe
: 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(TQPopupMenu *opMenu, TQWidget* parent)
: ButtonContainer(opMenu, parent)
{
- embedButton( new KButton(this) );
+ if(KickerSettings::legacyKMenu())
+ embedButton( new KButton(this) );
+ else
+ embedButton( new KNewButton(this) );
_actions = PanelAppletOpMenu::KMenuEditor;
}
diff --git a/kicker/kicker/core/containerarea.cpp b/kicker/kicker/core/containerarea.cpp
index 7d63d562a..1bd80bc65 100644
--- a/kicker/kicker/core/containerarea.cpp
+++ b/kicker/kicker/core/containerarea.cpp
@@ -87,7 +87,8 @@ ContainerArea::ContainerArea(KConfig* _c,
m_immutable(_c->isImmutable()),
m_updateBackgroundsCalled(false),
m_layout(0),
- m_addAppletDialog(0)
+ m_addAppletDialog(0),
+ _autoScrollTimer(0, "ContainerArea::autoScrollTimer")
{
setBackgroundOrigin( WidgetOrigin );
diff --git a/kicker/kicker/core/kicker.cpp b/kicker/kicker/core/kicker.cpp
index de37c609e..d91e1eaf9 100644
--- a/kicker/kicker/core/kicker.cpp
+++ b/kicker/kicker/core/kicker.cpp
@@ -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 @@ Kicker::Kicker()
KGlobal::iconLoader()->addExtraDesktopThemes();
+ KGlobal::locale()->insertCatalogue("kdmgreet");
KGlobal::locale()->insertCatalogue("libkonq");
KGlobal::locale()->insertCatalogue("libdmctl");
KGlobal::locale()->insertCatalogue("libtaskbar");
@@ -212,7 +215,7 @@ bool Kicker::highlightMenuItem(const TQString &menuId)
void Kicker::showKMenu()
{
- MenuManager::the()->showKMenu();
+ MenuManager::the()->kmenuAccelActivated();
}
void Kicker::popupKMenu(const TQPoint &p)
diff --git a/kicker/kicker/core/kmenubase.ui b/kicker/kicker/core/kmenubase.ui
new file mode 100644
index 000000000..1adb59b38
--- /dev/null
+++ b/kicker/kicker/core/kmenubase.ui
@@ -0,0 +1,300 @@
+
+KMenuBase
+
+
+ KMenu
+
+
+
+ 0
+ 0
+ 723
+ 580
+
+
+
+ KMenu
+
+
+ MShadow
+
+
+ MShape
+
+
+
+ m_search
+
+
+
+ 20
+ 40
+ 190
+ 54
+
+
+
+
+ unnamed
+
+
+ 0
+
+
+ 0
+
+
+
+ m_searchFrame
+
+
+
+ 5
+ 0
+ 0
+ 0
+
+
+
+
+ 0
+ 52
+
+
+
+
+ 32767
+ 52
+
+
+
+ StyledPanel
+
+
+ Raised
+
+
+ 0
+
+
+
+ unnamed
+
+
+
+ layout18
+
+
+
+ unnamed
+
+
+
+ m_searchLabel
+
+
+ ParentOrigin
+
+
+
+ 14
+
+
+
+ Search:
+
+
+
+
+ m_kcommand
+
+
+
+ 7
+ 0
+ 0
+ 0
+
+
+
+
+
+ m_searchPixmap
+
+
+
+ 1
+ 1
+ 0
+ 0
+
+
+
+
+ 32
+ 32
+
+
+
+
+ 32
+ 32
+
+
+
+ PaletteBackground
+
+
+ ParentOrigin
+
+
+ true
+
+
+
+
+
+
+
+
+ spacer5_2
+
+
+ Horizontal
+
+
+ Preferred
+
+
+
+ 16
+ 20
+
+
+
+
+
+
+
+ m_footer
+
+
+
+ 20
+ 110
+ 407
+ 34
+
+
+
+
+ unnamed
+
+
+ 4
+
+
+ 4
+
+
+
+ m_userInfo
+
+
+
+ 3
+ 0
+ 0
+ 0
+
+
+
+ User <b>user</b> on <b>host</b>
+
+
+
+
+ spacer13_2
+
+
+ Horizontal
+
+
+ MinimumExpanding
+
+
+
+ 10
+ 20
+
+
+
+
+
+ m_branding
+
+
+
+ 4
+ 4
+ 0
+ 0
+
+
+
+
+ 90
+ 24
+
+
+
+
+
+
+ image0
+
+
+ true
+
+
+ true
+
+
+
+
+ spacer13
+
+
+ Horizontal
+
+
+ Fixed
+
+
+
+ 14
+ 20
+
+
+
+
+
+
+
+
+
+
+ 89504e470d0a1a0a0000000d494844520000005a0000001808060000007a38ea6500000122494441546881ed98610e83200c85c7e2a93c0087e6005c0b7f754152ea43a532ec972c512cf5f96c28d3c5183f467fbe4f0b780b66b41266b41266b412cbd302b4594348d2f5e8bd93e2e83a9a93e2ada21b397a51355e57d1794592695c954af16b08899b23e5f955f41a42a25fbbfcbe709a9ed0c9998eb25b3aa2f72e7aef4634fbdf395c3a72d3f346811c73f390b172fcac36eefc2a522172e3746fd1e8b3a2a579523e3ae7c6b9fbf434f46e764623cda18ce78cc973213950b108b99e1ee6235b398e050d44e2f2f1abb966e3f43eba5c0e466ba03df4d4fa0982b8469706b65469f9a0b57d271787beb89ab63b970da9c1b5c4ba59bf4723464b3de9eebfe0531a3de20e64ba6f1da3f50a62ca8a1e91e92a7a54cc6825cc6825cc682536f10e058bc1bcdf310000000049454e44ae426082
+
+
+
+ kmenubase.ui.h
+
+
+ init()
+
+
+
+ kcombobox.h
+
+
diff --git a/kicker/kicker/core/kmenubase.ui.h b/kicker/kicker/core/kmenubase.ui.h
new file mode 100644
index 000000000..e1ed1ac25
--- /dev/null
+++ b/kicker/kicker/core/kmenubase.ui.h
@@ -0,0 +1,9 @@
+#include
+
+void KMenuBase::init()
+{
+ XSetWindowAttributes attrs;
+ attrs.override_redirect = True;
+ XChangeWindowAttributes( qt_xdisplay(), winId(), CWOverrideRedirect, &attrs );
+ setWFlags( Qt::WType_Popup );
+}
diff --git a/kicker/kicker/core/main.cpp b/kicker/kicker/core/main.cpp
index 16090b9af..76e94a0e3 100644
--- a/kicker/kicker/core/main.cpp
+++ b/kicker/kicker/core/main.cpp
@@ -108,7 +108,7 @@ extern "C" KDE_EXPORT int kdemain( int argc, char ** argv )
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-2010, The KDE Team") );
aboutData.addAuthor("Timothy Pearson", I18N_NOOP("Current maintainer"), "kb9vqf@pearsoncomputing.net");
diff --git a/kicker/kicker/core/menumanager.cpp b/kicker/kicker/core/menumanager.cpp
index 908f6bdf9..61110de14 100644
--- a/kicker/kicker/core/menumanager.cpp
+++ b/kicker/kicker/core/menumanager.cpp
@@ -31,9 +31,12 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#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::the()
MenuManager::MenuManager(TQObject *parent)
: TQObject(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(), TQT_SIGNAL(applicationRemoved(const TQCString&)),
this, TQT_SLOT(applicationRemoved(const TQCString&)));
@@ -83,14 +90,8 @@ void MenuManager::slotSetKMenuItemActive()
m_kmenu->selectFirstItem();
}
-void MenuManager::showKMenu()
-{
- m_kmenu->showMenu();
-}
-
void MenuManager::popupKMenu(const TQPoint &p)
{
-// kdDebug(1210) << "popupKMenu()" << endl;
if (m_kmenu->isVisible())
{
m_kmenu->hide();
@@ -120,7 +121,7 @@ void MenuManager::unregisterKButton(PanelPopupButton *button)
m_kbuttons.remove(button);
}
-PanelPopupButton* MenuManager::findKButtonFor(TQPopupMenu* menu)
+PanelPopupButton* MenuManager::findKButtonFor(TQWidget* menu)
{
KButtonList::const_iterator itEnd = m_kbuttons.constEnd();
for (KButtonList::const_iterator it = m_kbuttons.constBegin(); it != itEnd; ++it)
@@ -173,7 +174,7 @@ void MenuManager::kmenuAccelActivated()
const TQSize 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
@@ -193,7 +194,6 @@ void MenuManager::kmenuAccelActivated()
menuParent = menuParent->parent();
}
-
button->showMenu();
}
}
@@ -217,7 +217,7 @@ TQCString MenuManager::createMenu(TQPixmap icon, TQString text)
void MenuManager::removeMenu(TQCString menu)
{
- bool iterate = true;
+ bool iterate = true, need_adjustSize = false;
ClientMenuList::iterator it = clientmenus.begin();
for (; it != clientmenus.end(); iterate ? ++it : it)
{
@@ -228,15 +228,17 @@ void MenuManager::removeMenu(TQCString menu)
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 TQCString& appRemoved)
{
- bool iterate = true;
+ bool iterate = true, need_adjustSize = false;
ClientMenuList::iterator it = clientmenus.begin();
for (; it != clientmenus.end(); iterate ? ++it : it)
{
@@ -247,9 +249,11 @@ void MenuManager::applicationRemoved(const TQCString& appRemoved)
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 TQCString &fun, const TQByteArray &data,
diff --git a/kicker/kicker/core/menumanager.h b/kicker/kicker/core/menumanager.h
index e9d7dfef4..1139b0b61 100644
--- a/kicker/kicker/core/menumanager.h
+++ b/kicker/kicker/core/menumanager.h
@@ -28,7 +28,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include
class PanelKMenu;
+class KMenu;
class KickerClientMenu;
+class KMenuStub;
class PanelPopupButton;
typedef TQValueList KButtonList;
@@ -50,13 +52,12 @@ public:
bool process(const TQCString &fun, const TQByteArray &data, TQCString& replyType, TQByteArray &reply);
// KMenu controls
- PanelKMenu* kmenu() { return m_kmenu; }
- void showKMenu();
+ KMenuStub* kmenu() { return m_kmenu; }
void popupKMenu(const TQPoint &p);
void registerKButton(PanelPopupButton *button);
void unregisterKButton(PanelPopupButton *button);
- PanelPopupButton* findKButtonFor(TQPopupMenu* menu);
+ PanelPopupButton* findKButtonFor(TQWidget* menu);
~MenuManager();
public slots:
@@ -67,7 +68,7 @@ protected slots:
void applicationRemoved(const TQCString&);
protected:
- PanelKMenu* m_kmenu;
+ KMenuStub* m_kmenu;
typedef TQValueList ClientMenuList;
ClientMenuList clientmenus;
diff --git a/kicker/kicker/core/unhidetrigger.cpp b/kicker/kicker/core/unhidetrigger.cpp
index 7dcf1a127..0a5093a61 100644
--- a/kicker/kicker/core/unhidetrigger.cpp
+++ b/kicker/kicker/core/unhidetrigger.cpp
@@ -39,7 +39,7 @@ UnhideTrigger::UnhideTrigger()
, _lastXineramaScreen( -1 )
, enabledCount( 0 )
{
- _timer = new TQTimer( this );
+ _timer = new TQTimer( this, "UnhideTrigger" );
connect( _timer, TQT_SIGNAL(timeout()), TQT_SLOT(pollMouse()) );
}
diff --git a/kicker/kicker/interfaces/Makefile.am b/kicker/kicker/interfaces/Makefile.am
new file mode 100644
index 000000000..11f3f94b9
--- /dev/null
+++ b/kicker/kicker/interfaces/Makefile.am
@@ -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
diff --git a/kicker/kicker/interfaces/kickoff-search-plugin.cpp b/kicker/kicker/interfaces/kickoff-search-plugin.cpp
new file mode 100644
index 000000000..c229c85b0
--- /dev/null
+++ b/kicker/kicker/interfaces/kickoff-search-plugin.cpp
@@ -0,0 +1,37 @@
+/***************************************************************************
+ * Copyright (C) 2006 by Stephan Binner *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include "kickoff-search-plugin.h"
+#include
+
+KickoffSearch::Plugin::Plugin(TQObject *parent, const char* name )
+ :TQObject( parent, name )
+{
+}
+
+KickoffSearch::Plugin::~Plugin()
+{
+}
+
+KickoffSearch::KickoffSearchInterface* KickoffSearch::Plugin::kickoffSearchInterface()
+{
+ return static_cast( parent()->child( 0, "KickoffSearch::KickoffSearchInterface" ) );
+}
+
+#include "kickoff-search-plugin.moc"
diff --git a/kicker/kicker/interfaces/kickoff-search-plugin.h b/kicker/kicker/interfaces/kickoff-search-plugin.h
new file mode 100644
index 000000000..e91d079e7
--- /dev/null
+++ b/kicker/kicker/interfaces/kickoff-search-plugin.h
@@ -0,0 +1,106 @@
+/***************************************************************************
+ * Copyright (C) 2006 by Stephan Binner *
+ * Copyright (c) 2006 Debajyoti Bera *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#ifndef KICKOFF_SEARCH_PLUGIN_H
+#define KICKOFF_SEARCH_PLUGIN_H
+
+#include "kickoffsearchinterface.h"
+
+#include
+#include
+#include
+
+typedef enum {
+ ACTIONS = 0,
+ APPS,
+ BOOKMARKS,
+ NOTES,
+ MAILS,
+ FILES,
+ MUSIC,
+ WEBHIST,
+ CHATS,
+ FEEDS,
+ PICS,
+ VIDEOS,
+ DOCS,
+ OTHER,
+ num_categories
+} CATEGORY;
+
+class HitMenuItem
+{
+public:
+ HitMenuItem (int id, int category)
+ : id (id), category (category),score(0) { } /* dummy */
+ HitMenuItem (TQString name, TQString info, KURL uri, TQString mimetype, int id, int category, TQString icon=TQString::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
+ TQString display_name; // name to display
+ TQString display_info; // other information to display
+ KURL uri; // uri to open when clicked
+ TQString mimetype;
+ int id; // id of the item in the menu
+ int category;
+ TQString icon;
+ int score;
+ KService::Ptr service;
+
+ TQString quotedPath () const
+ {
+ return uri.path ().replace ('"', "\\\"");
+ }
+};
+
+namespace KickoffSearch {
+
+ class Plugin : public TQObject
+ {
+ Q_OBJECT
+
+ public:
+ Plugin(TQObject *parent, const char* name=0);
+ virtual ~Plugin();
+
+ virtual bool daemonRunning()=0;
+ virtual void query(TQString,bool)=0;
+
+ KickoffSearchInterface * kickoffSearchInterface();
+ };
+};
+
+#endif /* KICKOFF_SEARCH_PLUGIN_H */
diff --git a/kicker/kicker/interfaces/kickoffsearchinterface.cpp b/kicker/kicker/interfaces/kickoffsearchinterface.cpp
new file mode 100644
index 000000000..6df9d0630
--- /dev/null
+++ b/kicker/kicker/interfaces/kickoffsearchinterface.cpp
@@ -0,0 +1,27 @@
+/***************************************************************************
+ * Copyright (C) 2006 by Stephan Binner *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include "kickoffsearchinterface.h"
+
+KickoffSearch::KickoffSearchInterface::KickoffSearchInterface( TQObject* parent, const char* name )
+ :TQObject( parent, name )
+{
+}
+
+#include "kickoffsearchinterface.moc"
diff --git a/kicker/kicker/interfaces/kickoffsearchinterface.h b/kicker/kicker/interfaces/kickoffsearchinterface.h
new file mode 100644
index 000000000..91d28e7e6
--- /dev/null
+++ b/kicker/kicker/interfaces/kickoffsearchinterface.h
@@ -0,0 +1,46 @@
+/***************************************************************************
+ * Copyright (C) 2006 by Stephan Binner *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#ifndef KICKOFFSEARCHINTERFACE_H
+#define KICKOFFSEARCHINTERFACE_H
+
+#include
+
+class HitMenuItem;
+
+namespace KickoffSearch
+{
+ class KickoffSearchInterface :public TQObject
+ {
+ Q_OBJECT
+
+ public:
+ KickoffSearchInterface( TQObject* 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 */
+
diff --git a/kicker/kicker/interfaces/kickoffsearchplugin.desktop b/kicker/kicker/interfaces/kickoffsearchplugin.desktop
new file mode 100644
index 000000000..137d10a1d
--- /dev/null
+++ b/kicker/kicker/interfaces/kickoffsearchplugin.desktop
@@ -0,0 +1,4 @@
+[Desktop Entry]
+Type=ServiceType
+X-KDE-ServiceType=KickoffSearch/Plugin
+Comment=A search plugin for Kickoff
diff --git a/kicker/kicker/plugins/Makefile.am b/kicker/kicker/plugins/Makefile.am
new file mode 100644
index 000000000..bab1011f9
--- /dev/null
+++ b/kicker/kicker/plugins/Makefile.am
@@ -0,0 +1,24 @@
+INCLUDES = -I$(top_srcdir)/interfaces $(all_includes) $(LIBBEAGLE_CFLAGS) $(GLIB_CFLAGS)
+METASOURCES = AUTO
+
+# Install this plugin in the KDE modules directory
+kde_module_LTLIBRARIES = kickoffsearch_beagle.la
+
+# Srcs for the plugin
+kickoffsearch_beagle_la_SOURCES = kickoff-beagle-plugin.cpp beaglesearch.cpp
+
+# Libs needed by the plugin
+kickoffsearch_beagle_la_LIBADD = $(LIB_KPARTS) ../interfaces/libkickoffsearch_interfaces.la \
+ $(LIBBEAGLE_LIBADD) $(GLIB_LIBADD)
+
+# LD flags for the plugin
+# -module says: this is a module, i.e. something you're going to dlopen
+# so e.g. it has no version number like a normal shared lib would have.
+kickoffsearch_beagle_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries)
+
+# Install the desktop file needed to detect the plugin
+kde_services_DATA = kickoffsearch_beagle.desktop
+
+# i18n translation messages
+messages: rc.cpp
+ $(XGETTEXT) *.cpp *.h -o $(podir)/kickoffsearch_beagle.pot
diff --git a/kicker/kicker/plugins/beaglesearch.cpp b/kicker/kicker/plugins/beaglesearch.cpp
new file mode 100644
index 000000000..9f86c8fbd
--- /dev/null
+++ b/kicker/kicker/plugins/beaglesearch.cpp
@@ -0,0 +1,362 @@
+/*****************************************************************
+
+ Copyright (c) 2006 Debajyoti Bera
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+******************************************************************/
+
+#include "beaglesearch.h"
+
+#include
+#include
+#include
+#include
+#include
+
+void beagle_init ()
+{
+ g_type_init ();
+}
+
+// ---------------- Hit ---------------------------
+
+Hit::Hit (BeagleHit *_hit) : processed (false)
+{
+ hit = beagle_hit_ref (_hit);
+}
+
+Hit::~Hit ()
+{
+ beagle_hit_unref (hit);
+ if (! processed)
+ return;
+ TQDictIterator it (property_map);
+ for( ; it.current(); ++it )
+ ((TQStringList *)it.current())->clear ();
+
+}
+
+void Hit::processProperties ()
+{
+ processed = true;
+ GSList *prop_list = beagle_hit_get_all_properties (hit);
+ GSList *it;
+ property_map.setAutoDelete (true);
+ for (it = prop_list; it; it = it->next) {
+ BeagleProperty *property = (BeagleProperty *) it->data;
+ TQString key = TQString::fromUtf8 (beagle_property_get_key (property));
+ if (! property_map [key])
+ property_map.insert (key, new TQStringList ());
+ property_map [key]->append (TQString::fromUtf8 (beagle_property_get_value (property)));
+ }
+ g_slist_free (prop_list);
+}
+
+const TQString Hit::operator[] (TQString prop_name)
+{
+ if (! processed)
+ processProperties ();
+
+ TQStringList *prop_list = property_map [prop_name];
+ if (! prop_list)
+ return TQString::null;
+ if (prop_list->count () != 1)
+ return TQString::null;
+ return (TQString)prop_list->first ();
+}
+
+// ---------------- BeagleSearch ------------------
+
+BeagleSearchResult::BeagleSearchResult(int client_id)
+ : client_id (client_id), total (0)
+{
+ hitlist = new TQPtrList;
+ hitlist->setAutoDelete (true);
+}
+
+
+BeagleSearchResult::~BeagleSearchResult()
+{
+ // everything is set to autodelete
+}
+
+void BeagleSearchResult::addHit(BeagleHit *_hit)
+{
+ Hit *hit = new Hit (_hit);
+ hitlist->prepend (hit);
+}
+
+const TQPtrList *BeagleSearchResult::getHits () const
+{
+ return hitlist;
+}
+
+
+static int total_hits;
+
+static void print_feed_item_hit (BeagleHit *hit)
+{
+ const char *text;
+
+ if (beagle_hit_get_one_property (hit, "dc:title", &text))
+ g_print ("Blog: %s\n", text);
+}
+
+static void print_file_hit (BeagleHit *hit)
+{
+ g_print ("File: %s, (%s)\n", beagle_hit_get_uri (hit), beagle_hit_get_mime_type (hit));
+}
+
+static void print_other_hit (BeagleHit *hit)
+{
+ const char *text;
+
+ g_print ("%s (%s)", beagle_hit_get_uri (hit),
+ beagle_hit_get_source (hit));
+ if (beagle_hit_get_one_property (hit, "dc:title", &text))
+ g_print ("title = %s\n", text);
+}
+
+static void print_hit (BeagleHit *hit)
+{
+ if (strcmp (beagle_hit_get_type (hit), "FeedItem") == 0) {
+ print_feed_item_hit (hit);
+ }
+ else if (strcmp (beagle_hit_get_type (hit), "File") == 0) {
+ print_file_hit (hit);
+ } else {
+ print_other_hit (hit);
+ }
+}
+
+// ---------------- BeagleSearchClient ------------------
+
+void BeagleSearchClient::run ()
+{
+ kdDebug () << "Starting query ..." << endl;
+
+ TQTime query_timer;
+ query_timer.start ();
+
+ g_signal_connect (query, "hits-added",
+ G_CALLBACK (hitsAddedSlot),
+ this);
+ g_signal_connect (query, "finished",
+ G_CALLBACK (finishedSlot),
+ this);
+ beagle_client_send_request_async (client,
+ BEAGLE_REQUEST (query),
+ NULL);
+ g_main_loop_run (main_loop);
+ kdDebug () << "Finished query ..." << endl;
+
+ TQCustomEvent *ev;
+ if (collate_results) {
+ result->query_msec = query_timer.elapsed ();
+
+ ev = new TQCustomEvent (RESULTFOUND, result);
+ TQApplication::postEvent (object, ev);
+ }
+
+ ev = new TQCustomEvent (KILLME, this);
+ TQApplication::postEvent (object, ev);
+
+}
+
+void BeagleSearchClient::stopClient ()
+{
+ if (finished ())
+ return; // duh!
+ kdDebug () << "Query thread " << id << " not yet finished ..." << endl;
+ // get ready for suicide
+ client_mutex->lock ();
+ kill_me = true;
+ g_signal_handlers_disconnect_by_func (
+ query,
+ (void *)hitsAddedSlot,
+ this);
+ g_signal_handlers_disconnect_by_func (
+ query,
+ (void *)finishedSlot,
+ this);
+ g_main_loop_quit (main_loop);
+ client_mutex->unlock ();
+}
+
+void BeagleSearchClient::hitsAddedSlot (BeagleQuery *query,
+ BeagleHitsAddedResponse *response,
+ BeagleSearchClient *bsclient)
+{
+ GSList *hits, *l;
+ gint i;
+ gint nr_hits;
+
+ // check if we are supposed to be killed
+ bsclient->client_mutex->lock ();
+ if (bsclient->kill_me) {
+ kdDebug () << "Suicide time before processing" << endl;
+ bsclient->client_mutex->unlock ();
+ return;
+ }
+ bsclient->client_mutex->unlock ();
+
+ hits = beagle_hits_added_response_get_hits (response);
+
+ nr_hits = g_slist_length (hits);
+ total_hits += nr_hits;
+ g_print ("Found hits (%d) at %ld:\n", nr_hits, time (NULL));
+
+ BeagleSearchResult *search_result;
+ if (! bsclient->collate_results)
+ search_result = new BeagleSearchResult (bsclient->id);
+ else
+ search_result = bsclient->result;
+ search_result->total += nr_hits;
+
+ for (l = hits, i = 1; l; l = l->next, ++i) {
+ //g_print ("[%d] ", i);
+ //print_hit (BEAGLE_HIT (l->data));
+ //g_print ("\n");
+
+ search_result->addHit(BEAGLE_HIT (l->data));//hit);
+ }
+ g_print ("[%ld] hits adding finished \n", time (NULL));
+
+ // check if we are supposed to be killed
+ bsclient->client_mutex->lock ();
+ if (bsclient->kill_me) {
+ kdDebug () << "Suicide time before sending ..." << endl;
+ bsclient->client_mutex->unlock ();
+ if (! bsclient->collate_results)
+ delete search_result;
+ return;
+ }
+ bsclient->client_mutex->unlock ();
+
+ // time to send back results, if user asked so
+ if (bsclient->collate_results)
+ return;
+ TQCustomEvent *ev = new TQCustomEvent (RESULTFOUND, search_result);
+ g_print ("[%ld] event notified \n", time (NULL));
+ TQApplication::postEvent (bsclient->object, ev);
+}
+
+void BeagleSearchClient::finishedSlot (BeagleQuery *query,
+ BeagleFinishedResponse *response,
+ BeagleSearchClient *bsclient)
+{
+ // check if we are supposed to be killed
+ bsclient->client_mutex->lock ();
+ bool should_kill = bsclient->kill_me;
+ TQObject* receiver = bsclient->object;
+ bsclient->client_mutex->unlock ();
+
+ if (should_kill)
+ return;
+
+ g_main_loop_quit (bsclient->main_loop);
+
+ if (bsclient->collate_results)
+ return; // if we are collating, everything will be send from a central place
+ if (receiver) {
+ TQCustomEvent *ev = new TQCustomEvent (SEARCHOVER, bsclient);
+ g_print ("[%ld] query finish notified \n", time (NULL));
+ TQApplication::postEvent (receiver, ev);
+ }
+}
+
+// ----------------- BeagleUtil -------------------
+
+BeagleQuery *
+BeagleUtil::createQueryFromString (TQString query_str,
+ TQStringList &sources_menu,
+ TQStringList &types_menu,
+ int max_hits_per_source)
+{
+ BeagleQuery *beagle_query = beagle_query_new ();
+ beagle_query_set_max_hits (beagle_query, max_hits_per_source); // this is per source!
+
+ kdDebug () << "Creating query from \"" << query_str << "\"" << endl;
+ for ( TQStringList::Iterator it = sources_menu.begin(); it != sources_menu.end(); ++it )
+ beagle_query_add_source (beagle_query, g_strdup ((*it).utf8 ()));
+
+ for ( TQStringList::Iterator it = types_menu.begin(); it != types_menu.end(); ++it )
+ beagle_query_add_hit_type (beagle_query, g_strdup ((*it).utf8 ()));
+
+ TQStringList query_terms;
+ TQString start_date, end_date;
+ TQStringList words = TQStringList::split (' ', query_str, false);
+ for ( TQStringList::Iterator it = words.begin(); it != words.end(); ++it ) {
+ TQStringList key_value_pair = TQStringList::split ('=', *it, false);
+ if (key_value_pair.count () == 1)
+ query_terms += *it;
+ else if (key_value_pair.count () == 2) {
+ TQString key = key_value_pair [0].lower ();
+ TQString value = key_value_pair [1];
+ if (key == "mime")
+ beagle_query_add_mime_type (beagle_query, g_strdup (value.utf8 ()));
+ else if (key == "type")
+ beagle_query_add_hit_type (beagle_query, g_strdup (value.utf8 ()));
+ else if (key == "source")
+ beagle_query_add_source (beagle_query, g_strdup (value.utf8 ()));
+ else if (key == "start")
+ start_date = value;
+ else if (key == "end")
+ end_date = value;
+ else
+ query_terms += *it;
+ } else
+ query_terms += *it;
+ }
+
+ beagle_query_add_text (beagle_query, g_strdup (query_terms.join (" ").utf8 ()));
+ kdDebug () << "Adding query text:" << query_terms.join (" ").utf8 () << endl;
+
+ if (start_date.isNull () && end_date.isNull ())
+ return beagle_query;
+
+ //kdDebug () << "Handling dates ..." << endl;
+ BeagleQueryPartDate * date_part = beagle_query_part_date_new ();
+ if (! start_date.isNull ())
+ beagle_query_part_date_set_start_date (date_part, timestringToBeagleTimestamp (start_date));
+ if (! end_date.isNull ())
+ beagle_query_part_date_set_end_date (date_part, timestringToBeagleTimestamp (end_date));
+ beagle_query_add_part (beagle_query, BEAGLE_QUERY_PART (date_part));
+
+ return beagle_query;
+}
+
+// timestring format allowed YYYYmmDD
+BeagleTimestamp *
+BeagleUtil::timestringToBeagleTimestamp(TQString timestring)
+{
+ //kdDebug () << "datetime string:" << timestring << endl;
+ // FIXME: error check timestring format
+ if (timestring.isNull () || timestring.stripWhiteSpace () == "" || timestring.length() != 8 )
+ return beagle_timestamp_new_from_unix_time (TQDateTime::currentDateTime ().toTime_t ());
+ //TQDateTime dt = TQDateTime::fromString (timestring, Qt::ISODate);
+ struct tm tm_time;
+ time_t timet_time;
+ time (&timet_time);
+ localtime_r (&timet_time, &tm_time);
+ strptime (timestring.ascii(), "%Y%m%d", &tm_time);
+ tm_time.tm_sec = tm_time.tm_min = tm_time.tm_hour = 0;
+ //kdDebug() << asctime (&tm_time) << endl;
+ timet_time = mktime (&tm_time);
+ return beagle_timestamp_new_from_unix_time (timet_time);
+}
+
diff --git a/kicker/kicker/plugins/beaglesearch.h b/kicker/kicker/plugins/beaglesearch.h
new file mode 100644
index 000000000..e192f6af3
--- /dev/null
+++ b/kicker/kicker/plugins/beaglesearch.h
@@ -0,0 +1,234 @@
+/*****************************************************************
+
+ Copyright (c) 2006 Debajyoti Bera
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+******************************************************************/
+
+#ifndef BEAGLESEARCH_H
+#define BEAGLESEARCH_H
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+extern "C" {
+#include
+#include
+}
+
+// BeagleSearchClient sends 3 types of events
+// when results are to be sent as they arrive,
+// - RESULTFOUND : when result is found
+// - SEARCHOVER : when search is over
+// - KILLME : just before thread finishes - used to cleanup the thread object
+// when results are to be sent after receiving all of them
+// - RESULTFOUND : when all results are obtained
+// - KILLME : just before thread finishes - used to cleanup the thread object
+#define RESULTFOUND (TQEvent::Type)1001 /* TQEvent::User + 1 */
+#define SEARCHOVER (TQEvent::Type)1002 /* TQEvent::User + 2 */
+#define KILLME (TQEvent::Type)1003 /* TQEvent::User + 3 */
+
+class TQStringList;
+
+// IMPORTANT: Call this before any beagle calls
+void beagle_init ();
+
+class Hit {
+public:
+ Hit (BeagleHit *_hit);
+ ~Hit ();
+
+ // convenience wrappers
+ // remember that the hit values are utf8 strings
+ const KURL getUri () const { return KURL (TQString::fromUtf8 (beagle_hit_get_uri (hit)));}
+ const TQString getType () const { return TQString::fromUtf8 (beagle_hit_get_type (hit));}
+ const TQString getMimeType () const { return TQString::fromUtf8 (beagle_hit_get_mime_type (hit));}
+ const TQString getSource () const { return TQString::fromUtf8 (beagle_hit_get_source (hit));}
+ const KURL getParentUri () const { return KURL (TQString::fromUtf8 (beagle_hit_get_parent_uri (hit)));}
+ const TQDict& getAllProperties ()
+ {
+ if (! processed)
+ processProperties ();
+ return property_map;
+ }
+ const TQStringList* getProperties (TQString prop_name)
+ {
+ if (! processed)
+ processProperties ();
+ return property_map [prop_name];
+ }
+ const TQString operator[] (TQString prop_name);
+
+private:
+ BeagleHit *hit;
+ TQDict property_map;
+ // not every hit may be used. so, do a lazy processing of property_map
+ bool processed;
+ void processProperties ();
+};
+
+class BeagleSearchResult{
+public:
+ BeagleSearchResult(int client_id);
+ ~BeagleSearchResult();
+ void addHit (BeagleHit *hit);
+ TQString getHitCategory (Hit *hit);
+
+ // id of the bsclient
+ int client_id;
+ // time taken to finish query
+ int query_msec;
+ // total number of results in this query
+ int total;
+
+ const TQPtrList *getHits () const;
+
+private:
+ // lists of hits
+ TQPtrList *hitlist;
+};
+
+// caller should delete bsclient->result and bsclient
+class BeagleSearchClient : public TQThread {
+public:
+ // passing NULL for client makes bsclient create client itself and
+ // delete it later
+ BeagleSearchClient (int id,
+ TQObject *y,
+ BeagleClient *client,
+ BeagleQuery *query,
+ bool collate_results)
+ : id (id), kill_me (false), object (y), client (client),
+ query (query), destroy_client (false), collate_results (collate_results)
+ {
+ if (client == NULL) {
+ client = beagle_client_new (NULL);
+ destroy_client = true;
+ }
+
+// if (client == NULL)
+// throw -1;
+
+ main_loop = g_main_loop_new (NULL, FALSE);
+ if (collate_results)
+ result = new BeagleSearchResult (id);
+
+ client_mutex = new TQMutex ();
+ }
+
+ // It is never safe to delete BeagleSearchClient directly, the thread might still be running
+ ~BeagleSearchClient ()
+ {
+ if (! finished ()) {
+ kdDebug () << "Thread " << id << " still running. Waiting.........." << endl;
+ wait ();
+ }
+
+ if (destroy_client)
+ g_object_unref (client);
+ g_main_loop_unref (main_loop);
+ g_object_unref (query);
+ kdDebug() << "Deleting client ..." << id << endl;
+ delete client_mutex;
+ }
+
+private:
+ static void hitsAddedSlot (BeagleQuery *query,
+ BeagleHitsAddedResponse *response,
+ BeagleSearchClient *bsclient);
+
+ static void finishedSlot (BeagleQuery *query,
+ BeagleFinishedResponse *response,
+ BeagleSearchClient *bsclient);
+
+public:
+ // run() starts the query and sends the result as follows:
+ // - either wait till get back all results and send it as RESULTFOUND
+ // - or, send results as it gets them as RESULTFOUND and
+ // send SEARCHOVER when finished
+ // collate_results controls the behaviour
+ virtual void run ( );
+
+ // after stopClient() is called, application can safely go and remove previous menu entries
+ // - i.e. after stopClient is called, app doesnt except the eventhandler to receive any results
+ // - use client_id to determine which is the current client, set it right after stopclient
+ // - Eventhandler checks client id, if it is current, it adds stuff to the menu
+ // else, it discards everything
+ // Once eventhandler is being processed, doQuery() wont be called and vice versa
+ // so no need to serialize eventhandler and doquery
+ //
+ // stopClient needs to make sure that once it is called, the thread is finished asap. Use a mutex
+ // to serialize actions. callbacks need to use mutex too.
+ // stopclient has to remove signal handlers to prevent further signal calls, set kill_me flag
+ // and quite main loop
+ // stopClient can be called at the following times:
+ // - Waiting for the first result:
+ // nothing extra
+ // - in hitsAddedSlot, processing results
+ // in callback, before processing, if killme is set, just return.
+ // - in hitsAddedSlot, after sending results
+ // before sending, if killme is set, dont send results
+ // (doing it twice in hitsAdded because forming BeagleSearchResult can take time)
+ // - Waiting for more results
+ // nothing extra
+ // - in finishedSlot, before sending finishedMsg
+ // if killme is set, just return
+ // - in finishedSlot, after sending finishedMsg
+ // if killme is set, just return
+ // in Run(), when return from mainloop, if killme is set, dont do anything more but call delete this
+ void stopClient ();
+
+ // id of the client
+ // this is required in case applications fires many clients in rapid succession
+ int id;
+
+ GMainLoop * main_loop;
+ BeagleSearchResult *result;
+
+ // this is set if the client is obsolete now i.e.
+ // the application doesnt need the results from the client anymore
+ bool kill_me;
+private:
+ // the application; need this to send events to the application
+ TQObject *object;
+ // mutex to control setting the kill_me shared variable
+ TQMutex *client_mutex;
+ BeagleClient *client;
+ BeagleQuery *query;
+ // should the client be destroyed by the client
+ // if the client created it, then most probably it should
+ bool destroy_client;
+ bool collate_results;
+};
+
+class BeagleUtil {
+public:
+
+ static BeagleQuery *createQueryFromString (TQString query_str,
+ TQStringList &sources,
+ TQStringList &types,
+ int max_hits_per_source = 100);
+ static BeagleTimestamp *timestringToBeagleTimestamp (TQString timestring);
+};
+
+#endif
diff --git a/kicker/kicker/plugins/kickoff-beagle-plugin.cpp b/kicker/kicker/plugins/kickoff-beagle-plugin.cpp
new file mode 100644
index 000000000..3cad77ca4
--- /dev/null
+++ b/kicker/kicker/plugins/kickoff-beagle-plugin.cpp
@@ -0,0 +1,499 @@
+/***************************************************************************
+ * Copyright (C) 2006 by Stephan Binner *
+ * Copyright (c) 2006 Debajyoti Bera *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include "kickoff-beagle-plugin.h"
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+TQString dc_identifier = "dc:identifier";
+TQString dc_title = "dc:title";
+TQString parent_dc_title = "parent:dc:title";
+TQString exactfilename = "beagle:ExactFilename";
+TQString fixme_name = "fixme:Name";
+TQString beagle_filename = "beagle:Filename";
+TQString fixme_attachment_title = "fixme:attachment_title";
+TQString fixme_hasattachments = "fixme:hasAttachments";
+TQString parent_prefix = "parent:";
+TQString fixme_folder = "fixme:folder";
+TQString fixme_categories = "fixme:Categories";
+TQString fixme_comment = "fixme:Comment";
+TQString fixme_width = "fixme:width";
+TQString fixme_height = "fixme:height";
+TQString fixme_from_address = "fixme:from_address";
+TQString fixme_artist = "fixme:artist";
+TQString fixme_album = "fixme:album";
+TQString dc_source = "dc:source";
+TQString dc_publisher = "dc:publisher";
+TQString digikam_tag = "digikam:Tag";
+TQString fixme_speakingto = "fixme:speakingto";
+TQString fixme_starttime = "fixme:starttime";
+TQString comma_string = ",";
+TQString vCard_FN = "vCard:FN";
+TQString vCard_PREFEMAIL = "vCard:PREFEMAIL";
+TQString fixme_uid = "fixme:uid";
+
+static CATEGORY getHitCategory (Hit *hit)
+{
+ TQString hittype = hit->getType();
+ TQString hitsource = hit->getSource();
+
+ // if hit source is None, dont handle it. Might be anthrax-envelope :)
+ if (hitsource.isNull())
+ return OTHER;
+
+ if (hitsource == "documentation")
+ return DOCS;
+
+ if (hittype == "IMLog")
+ return CHATS;
+
+ // sure shots
+ if (hittype == "FeedItem")
+ return FEEDS;
+ if (hittype == "WebHistory")
+ return WEBHIST;
+ if (hittype == "MailMessage")
+ return MAILS;
+ if (hittype == "Note")
+ return NOTES;
+
+ // check for applications
+ if (hittype == "File" && (*hit) ["beagle:FilenameExtension"] == ".desktop")
+ return APPS;
+
+ // check for music
+ TQString hitmimetype = hit->getMimeType();
+ if (hitsource == "Amarok"
+ || hitmimetype.startsWith ("audio")
+ || hitmimetype == "application/ogg")
+ return MUSIC; // not an exhaustive search
+
+ // check for images from files
+ if (hitsource == "Files" && hitmimetype.startsWith ("image"))
+ return PICS;
+
+ if (hitsource == "Files" && hitmimetype.startsWith ("video"))
+ return VIDEOS;
+
+ if (hitsource == "Files")
+ return FILES;
+
+ if (hitsource == "KAddressBook")
+ return ACTIONS;
+
+ return OTHER;
+}
+
+K_EXPORT_COMPONENT_FACTORY( kickoffsearch_beagle,
+ KGenericFactory( "kickoffsearch_beagle" ) )
+
+KickoffBeaglePlugin::KickoffBeaglePlugin(TQObject *parent, const char* name, const TQStringList&)
+ : KickoffSearch::Plugin(parent, name ), genericTitle( true )
+{
+ g_type_init ();
+ current_beagle_client = NULL;
+}
+
+bool KickoffBeaglePlugin::daemonRunning()
+{
+ return beagle_util_daemon_is_running();
+}
+
+void KickoffBeaglePlugin::query(TQString term, bool _genericTitle)
+{
+ genericTitle = _genericTitle;
+ current_query_str = term;
+
+ // Beagle search
+ if (current_beagle_client != NULL) {
+ kdDebug () << "Previous client w/id " << current_beagle_client->id << " still running ... ignoring it." << endl;
+ current_beagle_client->stopClient ();
+ }
+ current_beagle_client_id = KApplication::random ();
+ kdDebug () << "Creating client with id:" << current_beagle_client_id << endl;
+
+ BeagleClient *beagle_client = beagle_client_new (NULL);
+ if (beagle_client == NULL) {
+ kdDebug() << "beagle service not running ..." << endl;
+ return;
+ }
+
+ TQStringList sources, types;
+ BeagleQuery *beagle_query = BeagleUtil::createQueryFromString (term, sources, types, 99); // maximum 99 results, if this doesnt work, blame the stars
+
+ current_beagle_client = new BeagleSearchClient (
+ current_beagle_client_id,
+ this,
+ beagle_client,
+ beagle_query,
+ false);
+ current_beagle_client->start();
+// kdDebug () << "Query dispatched at " << time (NULL) << endl;
+}
+
+void KickoffBeaglePlugin::cleanClientList ()
+{
+ toclean_list_mutex.lock ();
+ BeagleSearchClient *old_client = toclean_client_list.take (0);
+ if (old_client != NULL) { // failsafe
+ kdDebug () << "Cleanup old client " << old_client->id << endl;
+ delete old_client;
+ }
+ toclean_list_mutex.unlock ();
+}
+
+void KickoffBeaglePlugin::customEvent (TQCustomEvent *e)
+{
+ if (e->type () == RESULTFOUND) {
+// kdDebug () << "Quick query thread at " << time (NULL) << " with current_id=" << current_beagle_client_id << " finished ..." << endl;
+ BeagleSearchResult *result = (BeagleSearchResult *) e->data ();
+ if (current_beagle_client_id != result->client_id) {
+ kdDebug () << "Stale result from " << result->client_id << endl;
+ delete result;
+ // FIXME: Should I also free e ?
+ } else {
+ kdDebug () << "Good results ...total=" << result->total << endl;
+ showResults (result);
+ }
+ //KPassivePopup::message( "This is the message", this );
+ } else if (e->type () == SEARCHOVER) {
+ BeagleSearchClient *client = (BeagleSearchClient *) e->data ();
+ if (client == NULL) {
+// kdDebug () << "Query finished event at " << time (NULL) << " but client is already deleted" << endl;
+ return;
+ }
+// kdDebug () << "Query finished event at " << time (NULL) << " for id=" << client->id << endl;
+ if (current_beagle_client_id == client->id) {
+ kickoffSearchInterface()->searchOver();
+ current_beagle_client = NULL; // important !
+ }
+ } else if (e->type () == KILLME) {
+ BeagleSearchClient *client = (BeagleSearchClient *) e->data ();
+ if (client->finished ())
+ delete client;
+ else {
+ // add client to cleanup list
+ toclean_list_mutex.lock ();
+ toclean_client_list.append (client);
+ kdDebug () << "Scheduling client to be deleted in 500ms" << endl;
+ toclean_list_mutex.unlock ();
+ TQTimer::singleShot (500, this, TQT_SLOT (cleanClientList ()));
+ }
+ }
+}
+
+// this method decides what to display in the result list
+HitMenuItem *KickoffBeaglePlugin::hitToHitMenuItem (int category, Hit *hit)
+{
+ TQString title, info, mimetype, icon;
+ int score = 0;
+ KURL uri;
+
+#if 0
+ kdDebug() << "*** " << hit->getUri() << endl;
+ TQDict all = hit->getAllProperties();
+ TQDictIterator it( all );
+ for( ; it.current(); ++it )
+ kdDebug() << it.currentKey() << ": " << *(it.current()) << endl;
+#endif
+
+ switch (category) {
+ case FILES:
+ {
+ uri = hit->getUri ();
+ TQString uristr = uri.path ();
+ title = (*hit) [exactfilename];
+ int last_slash = uristr.findRev ('/', -1);
+ info = i18n("Folder: %1").arg(last_slash == 0 ? "/"
+ : uristr.section ('/', -2, -2));
+ }
+ break;
+ case ACTIONS:
+ {
+ if (hit->getSource()=="KAddressBook"){
+ title = i18n("Send Email to %1").arg((*hit)[vCard_FN]);
+ info = (*hit)[vCard_PREFEMAIL];
+ uri = "mailto:"+(*hit)[vCard_PREFEMAIL];
+ mimetype = hit->getMimeType ();
+ icon = "mail_new";
+
+ HitMenuItem * first_item=new HitMenuItem (title, info, uri, mimetype, 0, category, icon, score);
+ kickoffSearchInterface()->addHitMenuItem(first_item);
+
+ title =i18n("Open Addressbook at %1").arg((*hit)[vCard_FN]);
+ uri = "kaddressbook:/"+(*hit)[fixme_uid];
+ icon = "kaddressbook";
+ }
+ break;
+ }
+ case MAILS:
+ {
+ TQString prefix = TQString::null;
+ bool is_attachment = ((*hit) [parent_prefix + fixme_hasattachments] == "true");
+ bool has_parent = (! hit->getParentUri ().isEmpty ());
+ bool parent_mbox_file = false;
+ if (has_parent)
+ parent_mbox_file = ((*hit) [parent_prefix + fixme_folder] == TQString::null);
+
+ // Logic:
+ // If has_parent == false, everything is normal
+ // If has_parent == true, parent_mbox_file == false, everything is normal, use uri
+ // FIXME: If has_parent == true, parent_mbox_file == true, ???
+ // If has_parent == true, is_attachment == true, hit is attach and access with prefix "parent:", use parenturi
+ // Else, not attachment (multipart), access with prefix "parent:", use parenturi
+
+ if (has_parent && !parent_mbox_file) {
+ uri = hit->getParentUri ();
+ prefix = parent_prefix;
+ if (is_attachment)
+ title = (*hit) [fixme_attachment_title];
+ if (title.isEmpty ())
+ title = (*hit) [prefix + dc_title];
+ if (title.isEmpty ())
+ title = i18n("No subject");
+ if (is_attachment)
+ title = title.prepend (i18n("(Attachment) "));
+ info = (i18n("From %1").arg((*hit) [prefix + fixme_from_address]));
+ } else {
+ uri = hit->getUri ();
+ title = (*hit) [dc_title];
+ info = (i18n("From %1").arg((*hit) [fixme_from_address]));
+ }
+ }
+ mimetype = "message/rfc822"; // to handle attachment results
+ break;
+ case MUSIC:
+ uri = hit->getUri ();
+ title = (*hit) [exactfilename];
+ {
+ TQString artist = (*hit) [fixme_artist];
+ TQString album = (*hit) [fixme_album];
+ if (! artist.isEmpty ())
+ info = (i18n("By %1").arg(artist));
+ else if (! album.isEmpty ())
+ info = (i18n("From Album %1").arg(album));
+ else {
+ TQString uristr = uri.path ();
+ int last_slash = uristr.findRev ('/', -1);
+ info = i18n("Folder: %1")
+ .arg(last_slash == 0 ? "/" : uristr.section ('/', -2, -2));
+ }
+ }
+ break;
+ case VIDEOS:
+ uri = hit->getUri ();
+ title = (*hit) [exactfilename];
+ {
+ TQString uristr = uri.path ();
+ int last_slash = uristr.findRev ('/', -1);
+ info = i18n("Folder: %1").arg(last_slash == 0 ? "/" : uristr.section ('/', -2, -2));
+ }
+ break;
+ case WEBHIST:
+ uri = hit->getUri ();
+ title = (*hit) [dc_title];
+ title = title.replace(TQRegExp("\n")," ");
+ mimetype = "text/html";
+ if (title.isEmpty () || title.stripWhiteSpace ().isEmpty ()) {
+ title = uri.prettyURL ();
+ } else {
+ info = uri.host () + uri.path ();
+ }
+ break;
+ case FEEDS:
+ {
+ uri = KURL ((*hit) [dc_identifier]);
+ title = (*hit) [dc_title];
+ mimetype = "text/html";
+ TQString publisher = (*hit) [dc_publisher];
+ TQString source = (*hit) [dc_source];
+ if (! publisher.isEmpty ())
+ info = publisher;
+ else if (! source.isEmpty ())
+ info = source;
+ }
+ break;
+ case PICS:
+ {
+ uri = hit->getUri ();
+ title = (*hit) [exactfilename];
+ TQString width = (*hit) [fixme_width];
+ TQString height = (*hit) [fixme_height];
+ if (width.isEmpty () || height.isEmpty ()) {
+ TQString uristr = uri.path ();
+ int last_slash = uristr.findRev ('/', -1);
+ info = i18n("Folder: %1")
+ .arg(last_slash == 0 ? "/" : uristr.section ('/', -2, -2));
+ break;
+ }
+ info = (TQString (" (%1x%2)").arg (width).arg (height));
+ const TQStringList *tags = hit->getProperties (digikam_tag);
+ if (tags == NULL)
+ break;
+ TQString tags_string = tags->join (comma_string);
+ info += (" " + tags_string);
+ }
+ break;
+ case APPS:
+ {
+ uri = hit->getUri ();
+ title = (*hit) [dc_title];
+ KDesktopFile desktopfile(uri.path(),true);
+ if (genericTitle && !desktopfile.readGenericName().isEmpty()) {
+ title = desktopfile.readGenericName();
+ info = desktopfile.readName();
+ }
+ else {
+ title = desktopfile.readName();
+ info = desktopfile.readGenericName();
+ }
+ icon = desktopfile.readIcon();
+ TQString input = current_query_str.lower();
+ TQString command = desktopfile.readEntry("Exec");
+ if (command==input)
+ score = 100;
+ else if (command.find(input)==0)
+ score = 50;
+ else if (command.find(input)!=-1)
+ score = 10;
+ else if (title==input)
+ score = 100;
+ else if (title.find(input)==0)
+ score = 50;
+ else if (title.find(input)!=-1)
+ score = 10;
+ break;
+ }
+ break;
+ case NOTES:
+ {
+ uri = hit->getUri ();
+ title = (*hit) [dc_title];
+ title = i18n("Title: %1").arg(title.isEmpty() ? i18n("Untitled") : title);
+
+ if (hit->getSource()=="KNotes")
+ icon="knotes";
+ else
+ icon="contents2";
+ }
+ break;
+ case CHATS:
+ {
+ uri = hit->getUri ();
+ title = (*hit) [fixme_speakingto];
+ title = i18n("Conversation With %1").arg(title.isEmpty() ? i18n("Unknown Person") : title);
+ TQDateTime datetime;
+ datetime = datetimeFromString((*hit) [fixme_starttime]);
+ info=i18n("Date: %1").arg(KGlobal::locale()->formatDateTime(datetime,false));
+ if (hit->getMimeType()=="beagle/x-kopete-log")
+ icon="kopete";
+ else
+ icon="gaim";
+ }
+ break;
+ case DOCS:
+ {
+ uri = hit->getUri ();
+ title = (*hit) [dc_title];
+ if (title.isEmpty () || title.stripWhiteSpace ().isEmpty ())
+ title = uri.prettyURL ();
+ else {
+ TQString uristr = uri.path ();
+ int last_slash = uristr.findRev ('/', -1);
+ info = i18n("Folder: %1").arg(last_slash == 0 ? "/" : uristr.section ('/',
+ -2, -2));
+ }
+ }
+ break;
+ default:
+ return NULL;
+ }
+ if (mimetype.isEmpty ())
+ mimetype = hit->getMimeType ();
+ return new HitMenuItem (title, info, uri, mimetype, 0, category, icon, score);
+}
+
+void KickoffBeaglePlugin::showResults(BeagleSearchResult *result)
+{
+ if (result->total == 0 ) {
+ // Dont report error from here ...
+ kdDebug() << "No matches found" << endl;
+ delete result;
+ return;
+ }
+
+ const TQPtrList *hits = result->getHits();
+ if (hits == NULL) {
+ kdDebug () << "Hmm... null" << endl;
+ delete result;
+ return;
+ }
+ kickoffSearchInterface()->initCategoryTitlesUpdate();
+
+ TQPtrListIterator it (*hits);
+ Hit *hit;
+ for (; (hit = it.current ()) != NULL; ++it) {
+ CATEGORY category = getHitCategory (hit);
+
+ // if category is not handled, continue
+ if (category == OTHER)
+ continue;
+
+ if ( category == APPS ) {
+ // we need to check if this is useful
+ KService cs( hit->getUri().path() );
+ if ( cs.noDisplay() )
+ continue;
+ }
+
+ if (!kickoffSearchInterface()->anotherHitMenuItemAllowed(category))
+ continue;
+
+ HitMenuItem *hit_item = hitToHitMenuItem (category, hit);
+
+ if (!hit_item)
+ continue;
+
+ kickoffSearchInterface()->addHitMenuItem(hit_item);
+ }
+
+ kickoffSearchInterface()->updateCategoryTitles();
+
+ delete result;
+}
+
+TQDateTime KickoffBeaglePlugin::datetimeFromString( const TQString& s)
+{
+ int year( s.mid( 0, 4 ).toInt() );
+ int month( s.mid( 4, 2 ).toInt() );
+ int day( s.mid( 6, 2 ).toInt() );
+ int hour( s.mid( 8, 2 ).toInt() );
+ int min( s.mid( 10, 2 ).toInt() );
+ int sec( s.mid( 12, 2 ).toInt() );
+ return TQDateTime(TQDate(year,month,day),TQTime(hour,min,sec));
+}
+
+#include "kickoff-beagle-plugin.moc"
diff --git a/kicker/kicker/plugins/kickoff-beagle-plugin.h b/kicker/kicker/plugins/kickoff-beagle-plugin.h
new file mode 100644
index 000000000..8288ba647
--- /dev/null
+++ b/kicker/kicker/plugins/kickoff-beagle-plugin.h
@@ -0,0 +1,64 @@
+/***************************************************************************
+ * Copyright (C) 2006 by Stephan Binner *
+ * Copyright (c) 2006 Debajyoti Bera *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#ifndef CAPITALIZEPLUGIN_H
+#define CAPITALIZEPLUGIN_H
+
+#include "../interfaces/kickoff-search-plugin.h"
+#include "beaglesearch.h"
+
+class KickoffBeaglePlugin :public KickoffSearch::Plugin
+{
+ Q_OBJECT
+
+public:
+ KickoffBeaglePlugin(TQObject *parent, const char* name, const TQStringList&);
+
+ void query(TQString, bool);
+ bool daemonRunning();
+
+protected slots:
+ // to clean beaglesearchclients
+ void cleanClientList ();
+
+private:
+ TQString current_query_str;
+
+ // all beagle activity is done through the BSC object
+ BeagleSearchClient *current_beagle_client;
+
+ // used to send notification from the beagle thread to the main event loop
+ virtual void customEvent (TQCustomEvent *e);
+
+ TQPtrList toclean_client_list;
+ TQMutex toclean_list_mutex;
+
+ // show the results
+ void showResults (BeagleSearchResult *);
+ HitMenuItem *hitToHitMenuItem (int category, Hit *hit);
+
+ // use a different id for each bsc client, and use that to separate stale responses from current ones
+ int current_beagle_client_id;
+
+ bool genericTitle;
+ TQDateTime datetimeFromString( const TQString& );
+};
+
+#endif /* CAPITALIZEPLUGIN_H */
diff --git a/kicker/kicker/plugins/kickoffsearch_beagle.desktop b/kicker/kicker/plugins/kickoffsearch_beagle.desktop
new file mode 100644
index 000000000..2904dcda6
--- /dev/null
+++ b/kicker/kicker/plugins/kickoffsearch_beagle.desktop
@@ -0,0 +1,6 @@
+[Desktop Entry]
+Name=Beagle Search
+Comment=Beagle search plugin for Kickoff search
+ServiceTypes=KickoffSearch/Plugin
+Type=Service
+X-KDE-Library=kickoffsearch_beagle
diff --git a/kicker/kicker/ui/Makefile.am b/kicker/kicker/ui/Makefile.am
index 1bd54777e..9384c28f5 100644
--- a/kicker/kicker/ui/Makefile.am
+++ b/kicker/kicker/ui/Makefile.am
@@ -1,39 +1,45 @@
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_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 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 clicklineedit.cpp
+ addappletvisualfeedback.cpp clicklineedit.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
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 clicklineedit.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
diff --git a/kicker/kicker/ui/addappletvisualfeedback.cpp b/kicker/kicker/ui/addappletvisualfeedback.cpp
index 38b48fe8e..acd82a066 100644
--- a/kicker/kicker/ui/addappletvisualfeedback.cpp
+++ b/kicker/kicker/ui/addappletvisualfeedback.cpp
@@ -51,6 +51,7 @@ AddAppletVisualFeedback::AddAppletVisualFeedback(AppletWidget* widget,
m_richText(0),
m_dissolveDelta(-1),
m_frames(1),
+ m_moveTimer(0, "m_moveTimer"),
m_dirty(false)
{
setFocusPolicy(NoFocus);
diff --git a/kicker/kicker/ui/appletop_mnu.cpp b/kicker/kicker/ui/appletop_mnu.cpp
index 59ca9c89e..55c181016 100644
--- a/kicker/kicker/ui/appletop_mnu.cpp
+++ b/kicker/kicker/ui/appletop_mnu.cpp
@@ -30,6 +30,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "appletop_mnu.h"
#include "container_button.h"
#include "containerarea.h"
+#include "kickerSettings.h"
PanelAppletOpMenu::PanelAppletOpMenu(int actions, TQPopupMenu *opMenu, const TQPopupMenu* appletsMenu,
const TQString & title, const TQString &icon,
@@ -159,6 +160,20 @@ PanelAppletOpMenu::PanelAppletOpMenu(int actions, TQPopupMenu *opMenu, const TQP
}
}
+ if ((actions & PanelAppletOpMenu::KMenuEditor))
+ {
+ if (needSeparator)
+ {
+ insertSeparator();
+ needSeparator = false;
+ }
+
+ if (KickerSettings::legacyKMenu())
+ insertItem(SmallIcon("kickoff"), i18n("Switch to Kickoff Menu Style"), this, TQT_SLOT(toggleLegacy()));
+ else
+ insertItem(SmallIcon("about_kde"), i18n("Switch to KDE Menu Style"), this, TQT_SLOT(toggleLegacy()));
+ }
+
if ((actions & PanelAppletOpMenu::KMenuEditor) && kapp->authorizeKAction("menuedit"))
{
if (needSeparator)
@@ -205,4 +220,11 @@ void PanelAppletOpMenu::keyPressEvent(TQKeyEvent* e)
TQPopupMenu::keyPressEvent(e);
}
+void PanelAppletOpMenu::toggleLegacy()
+{
+ KickerSettings::setLegacyKMenu(!KickerSettings::legacyKMenu());
+ KickerSettings::writeConfig();
+ Kicker::the()->restart();
+}
+
#include "appletop_mnu.moc"
diff --git a/kicker/kicker/ui/appletop_mnu.h b/kicker/kicker/ui/appletop_mnu.h
index e0b219552..4b396a83d 100644
--- a/kicker/kicker/ui/appletop_mnu.h
+++ b/kicker/kicker/ui/appletop_mnu.h
@@ -47,6 +47,9 @@ public:
signals:
void escapePressed();
+protected slots:
+ void toggleLegacy();
+
protected:
void keyPressEvent(TQKeyEvent* e);
};
diff --git a/kicker/kicker/ui/browser_mnu.cpp b/kicker/kicker/ui/browser_mnu.cpp
index 88ce30713..2250475b4 100644
--- a/kicker/kicker/ui/browser_mnu.cpp
+++ b/kicker/kicker/ui/browser_mnu.cpp
@@ -332,7 +332,7 @@ void PanelBrowserMenu::initialize()
if(_mimemap.count() > 0) {
if(!_mimecheckTimer)
- _mimecheckTimer = new TQTimer(this);
+ _mimecheckTimer = new TQTimer(this, "_mimecheckTimer");
connect(_mimecheckTimer, TQT_SIGNAL(timeout()), TQT_SLOT(slotMimeCheck()));
_mimecheckTimer->start(0);
diff --git a/kicker/kicker/ui/default-favs b/kicker/kicker/ui/default-favs
new file mode 100644
index 000000000..8cbff626d
--- /dev/null
+++ b/kicker/kicker/ui/default-favs
@@ -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
diff --git a/kicker/kicker/ui/flipscrollview.cpp b/kicker/kicker/ui/flipscrollview.cpp
new file mode 100644
index 000000000..ae96ebcaa
--- /dev/null
+++ b/kicker/kicker/ui/flipscrollview.cpp
@@ -0,0 +1,324 @@
+/*****************************************************************
+
+Copyright (c) 2006 Will Stephenson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#include
+#include
+#include
+#include
+
+#include "itemview.h"
+#include "flipscrollview.h"
+#include "kickerSettings.h"
+
+/* Flip scroll steps, as percentage of itemview width to scroll per
+ * step. Assumes the itemview is scrolled in ten steps */
+
+/* slow start, then fast */
+//static const double scrollSteps[] = { 0.05, 0.05, 0.1125, 0.1125, 0.1125, 0.1125, 0.1125, 0.1125, 0.1125, 0.1125 };
+
+/* slow fast slow */
+//static const double scrollSteps[] = { 0.05, 0.05, 0.13, 0.13, 0.15, 0.13, 0.13, 0.13, 0.05, 0.05 };
+
+/* slow veryfast slow */
+static const double scrollSteps[] = { 0.03, 0.03, 0.147, 0.147, 0.147, 0.147, 0.147, 0.147, 0.03, 0.028 };
+;
+
+BackFrame::BackFrame( TQWidget *parent )
+ : TQFrame( parent ), mouse_inside( false )
+{
+ setFrameStyle( TQFrame::NoFrame );
+ if ( TQApplication::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( TQPainter *p )
+{
+ TQColor gray( 230, 230, 230 );
+ if ( mouse_inside )
+ p->fillRect( 3, 3, width() - 6, height() - 6, colorGroup().color( TQColorGroup::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;
+ TQImage i = left_triangle.convertToImage().smoothScale( pixsize, pixsize );
+ TQPixmap tri;
+ tri.convertFromImage( i );
+
+ p->drawPixmap( ( width() - tri.width() ) / 2, ( height() - tri.height() ) / 2, tri );
+}
+
+void BackFrame::enterEvent( TQEvent *e )
+{
+ mouse_inside = true;
+ update();
+}
+
+void BackFrame::leaveEvent( TQEvent *e )
+{
+ mouse_inside = false;
+ update();
+}
+
+void BackFrame::mousePressEvent ( TQMouseEvent * e )
+{
+ emit clicked();
+}
+
+FlipScrollView::FlipScrollView( TQWidget * parent, const char * name )
+ : TQScrollView( parent, name ), mState( StoppedLeft ), mScrollDirection( 1 ), mShowBack( false )
+{
+ setVScrollBarMode( TQScrollView::AlwaysOff );
+ setHScrollBarMode( TQScrollView::AlwaysOff );
+ setFrameStyle( TQFrame::NoFrame );
+ mLeftView = new ItemView( this, "left_view" );
+ addChild( mLeftView );
+
+ mRightView = new ItemView( this, "right_view" );
+ addChild( mRightView );
+
+ mTimer = new TQTimer( this, "mTimer" );
+ connect( mTimer, TQT_SIGNAL( timeout() ), TQT_SLOT( slotScrollTimer() ) );
+
+ connect( mLeftView, TQT_SIGNAL( startService(KService::Ptr) ),
+ TQT_SIGNAL( startService(KService::Ptr) ) );
+ connect( mLeftView, TQT_SIGNAL( startURL(const TQString& ) ),
+ TQT_SIGNAL( startURL(const TQString& ) ) );
+ connect( mLeftView, TQT_SIGNAL( rightButtonPressed(TQListViewItem*,const TQPoint&,int) ),
+ TQT_SIGNAL( rightButtonPressed(TQListViewItem*,const TQPoint&,int) ) );
+ connect( mRightView, TQT_SIGNAL( startService(KService::Ptr) ),
+ TQT_SIGNAL( startService(KService::Ptr) ) );
+ connect( mRightView, TQT_SIGNAL( startURL(const TQString& ) ),
+ TQT_SIGNAL( startURL(const TQString& ) ) );
+ connect( mRightView, TQT_SIGNAL( rightButtonPressed(TQListViewItem*,const TQPoint&,int) ),
+ TQT_SIGNAL( rightButtonPressed(TQListViewItem*,const TQPoint&,int) ) );
+
+ // wild hack to make sure it has correct width
+ mLeftView->setVScrollBarMode( TQScrollView::AlwaysOn );
+ mRightView->setVScrollBarMode( TQScrollView::AlwaysOn );
+ mLeftView->setVScrollBarMode( TQScrollView::Auto );
+ mRightView->setVScrollBarMode( TQScrollView::Auto );
+
+ mBackrow = new BackFrame( this );
+ mBackrow->resize( 24, 100 );
+ connect( mBackrow, TQT_SIGNAL( clicked() ), TQT_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 ( TQResizeEvent * )
+{
+ 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 ( TQApplication::reverseLayout() )
+ moveChild( mRightView, width(), 0 );
+ else
+ moveChild( mRightView, width() + mBackrow->width(), 0 );
+ mRightView->resize( width() - mBackrow->width(), height() );
+ mLeftView->resize( width(), height() );
+ if ( TQApplication::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 ( TQApplication::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 {
+ TQListViewItem * child = currentView()->firstChild();
+ while( child ) {
+ KMenuItem* kitem = dynamic_cast(child);
+ if (kitem && kitem->menuPath()==mSelectMenuPath) {
+ currentView()->setSelected(child,true);
+ kdDebug() << "child repaint\n";
+ child->repaint();
+ break;
+ }
+ child = child->nextSibling();
+ }
+ }
+ }
+ mLeftView->setVScrollBarMode( TQScrollView::Auto );
+ mRightView->setVScrollBarMode( TQScrollView::Auto );
+ mTimer->stop();
+ mLeftView->setMouseMoveSelects( true );
+ mRightView->setMouseMoveSelects( true );
+ }
+}
+
+void FlipScrollView::flipScroll(const TQString& selectMenuPath)
+{
+ if ( mState == StoppedLeft )
+ {
+ mState = ScrollingRight;
+ mScrollDirection = 1;
+ }
+ else
+ {
+ mState = ScrollingLeft;
+ mScrollDirection = -1;
+ }
+
+ mLeftView->setVScrollBarMode( TQScrollView::AlwaysOff );
+ mRightView->setVScrollBarMode( TQScrollView::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"
diff --git a/kicker/kicker/ui/flipscrollview.h b/kicker/kicker/ui/flipscrollview.h
new file mode 100644
index 000000000..d2de2ab5e
--- /dev/null
+++ b/kicker/kicker/ui/flipscrollview.h
@@ -0,0 +1,118 @@
+/*****************************************************************
+
+Copyright (c) 2006 Will Stephenson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+/*
+ * Flip scroll menu
+ * Each level of the menu is a separate TQListView
+ * Child items are added to their own TQListView.
+ * When a parent is clicked, we look up its child menu and insert
+ * that in a TQScrollView, then scroll to it.
+ *
+ * Need to intercept TQListViewItems' parent param and instead of
+ * inserting directly into parent, insert into parent item's listview
+ *
+ * So need
+ * - adapted QLVI
+ * - wrap QLV and offer same interface
+ */
+
+#ifndef FLIPSCROLLVIEW_H
+#define FLIPSCROLLVIEW_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include "service_mnu.h"
+
+class ItemView;
+
+class BackFrame : public TQFrame
+{
+ Q_OBJECT
+
+public:
+ BackFrame( TQWidget *parent );
+ virtual void drawContents( TQPainter *p );
+
+ void enterEvent ( TQEvent * );
+ void leaveEvent( TQEvent * );
+ void mousePressEvent ( TQMouseEvent * e );
+
+signals:
+ void clicked();
+
+private:
+ TQPixmap left_triangle;
+ bool mouse_inside;
+};
+
+class FlipScrollView : public TQScrollView
+{
+ Q_OBJECT
+public:
+ enum State{ StoppedLeft, StoppedRight, ScrollingLeft, ScrollingRight };
+ FlipScrollView( TQWidget * 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 TQString& selectMenuPath = TQString::null);
+ void showBackButton(bool enable);
+ bool showsBackButton() const {return mShowBack;}
+
+protected slots:
+ void slotScrollTimer();
+
+signals:
+ void startService(KService::Ptr kservice);
+ void startURL(const TQString& u);
+ void rightButtonPressed(TQListViewItem*,const TQPoint&,int);
+ void backButtonClicked();
+
+protected:
+ void viewportResizeEvent ( TQResizeEvent * );
+
+private:
+ ItemView * mLeftView;
+ ItemView * mRightView;
+// ItemView * mCurrentView;
+ int mStepsRemaining;
+ State mState;
+ TQTimer * mTimer;
+ BackFrame *mBackrow;
+ TQString mSelectMenuPath;
+ int mScrollDirection;
+ bool mShowBack;
+};
+
+
+
+
+#endif
diff --git a/kicker/kicker/ui/itemview.cpp b/kicker/kicker/ui/itemview.cpp
new file mode 100644
index 000000000..dcb4760c1
--- /dev/null
+++ b/kicker/kicker/ui/itemview.cpp
@@ -0,0 +1,1257 @@
+/*****************************************************************
+
+Copyright (c) 1996-2000 the kicker authors. See file AUTHORS.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "client_mnu.h"
+#include "container_base.h"
+#include "global.h"
+#include "kbutton.h"
+#include "kicker.h"
+#include "kickerSettings.h"
+#include "konqbookmarkmanager.h"
+#include "menuinfo.h"
+#include "menumanager.h"
+#include "popupmenutitle.h"
+#include "quickbrowser_mnu.h"
+#include "recentapps.h"
+
+#include "k_mnu.h"
+#include "k_new_mnu.h"
+#include "itemview.h"
+
+// --------------------------------------------------------------------------
+
+KMenuItem::~KMenuItem()
+{
+ ItemView *listview = dynamic_cast( listView() );
+ if ( listview && listview->m_lastOne == this) {
+ listview->m_lastOne = 0;
+ listview->m_old_contentY = -1;
+ }
+}
+
+static double pointSize( double pixelSize, TQPaintDevice *w )
+{
+ return pixelSize * 72. / TQPaintDevice::x11AppDpiY( w->x11Screen () );
+}
+
+static int pixelSize( double pixelSize, TQPaintDevice *w )
+{
+ return qRound( pixelSize * TQPaintDevice::x11AppDpiY( w->x11Screen () ) / 72. );
+}
+
+void KMenuItem::init()
+{
+ setMultiLinesEnabled(true);
+ m_s = 0;
+ m_path = TQString::null;
+ m_icon = TQString::null;
+ m_menuPath = TQString::null;
+ setDragEnabled(true);
+ m_has_children = false;
+ m_old_width = -1;
+ if ( TQApplication::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 TQString& txt)
+{
+ m_title = txt;
+ setText( 0, txt );
+ setup();
+}
+
+void KMenuItem::setToolTip(const TQString& txt)
+{
+ m_tooltip = txt;
+}
+
+void KMenuItem::setDescription(const TQString& txt)
+{
+ m_description = txt;
+ setup();
+}
+
+void KMenuItem::setIcon(const TQString& icon, int size)
+{
+ m_icon = icon;
+ TQListViewItem::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;
+ TQListViewItem::setup();
+ setHeight( (int)QMAX( expected_height, pixelSize( title_font_size + description_font_size * 2.3, listView())));
+}
+
+void KMenuItem::paintCell(TQPainter* p, const TQColorGroup & cg, int column, int width, int align)
+{
+ ItemView *listview = static_cast( listView() );
+ int bottom = listView()->itemRect( this ).bottom();
+ int diff = bottom - listView()->viewport()->height();
+
+ KPixmap pm;
+ pm.resize( width, height() );
+ TQPainter 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( TQColorGroup::Background ),
+ KPixmapEffect::VerticalGradient );
+ p->drawPixmap( 0, 0, pm );
+ if ( listview->m_lastOne != this )
+ {
+ listview->m_lastOne = this;
+ listview->m_old_contentY = -1;
+ }
+ }
+ else
+ {
+ p->drawPixmap( 0, 0, pm );
+ if ( this == listview->m_lastOne ) {
+ if ( bottom < 0 )
+ listview->m_lastOne = static_cast( itemAbove() );
+ else
+ listview->m_lastOne = static_cast( itemBelow() );
+ listview->m_old_contentY = -1;
+ repaint();
+ }
+ }
+}
+
+void KMenuItem::makeGradient( KPixmap &off, const TQColor &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 );
+ TQPainter p( &off );
+ p.drawPixmap( off.width() - blend.width(), 0, blend );
+ p.end();
+}
+
+void KMenuItem::paintCellInter(TQPainter* p, const TQColorGroup & cg, int column, int width, int align)
+{
+ const bool reverseLayout = TQApplication::reverseLayout();
+
+ const BackgroundMode bgmode = listView()->viewport()->backgroundMode();
+ const TQColorGroup::ColorRole crole = TQPalette::backgroundRoleFromMode( bgmode );
+ TQColor backg = cg.color( crole );
+
+ if ( isSelected() )
+ backg = cg.color( TQColorGroup::Highlight );
+ p->fillRect( 0, 0, width, height(), backg );
+
+ TQFontMetrics 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, TQString::number( childCount () ) );
+
+ const TQPixmap * pix = pixmap( column );
+
+ if ( pix )
+ {
+ TQPixmap pix32 = *pix;
+
+ if ( pix->width() > pixsize )
+ {
+ TQImage 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;
+
+ TQFont f1 = p->font();
+ f1.setPointSizeFloat( title_font_size );
+ f1.setWeight( TQFont::Normal ); // TQFont::DemiBold == 63
+
+ TQFont f2 = p->font();
+ f2.setPointSizeFloat( description_font_size );
+ f2.setWeight( TQFont::Light );
+
+ int f1h = TQFontMetrics( f1 ).height();
+ int f2h = TQFontMetrics( 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;
+ TQPainter 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( TQColorGroup::HighlightedText ) );
+ else
+ pp.setPen( cg.color( TQColorGroup::Text ) );
+
+ pp.setFont( f1 );
+ pp.drawText( 0, 0, off.width(), off.height(), align, m_title );
+ pp.end();
+ if ( TQFontMetrics( f1 ).width( m_title ) > off.width() )
+ {
+ makeGradient( off, backg );
+ if ( !m_description.isEmpty() )
+ setToolTip( m_title + "
" + m_description );
+ else
+ setToolTip( m_title );
+ }
+ if ( reverseLayout )
+ p->drawPixmap( width - off.width() - r, spacing, off );
+ else
+ p->drawPixmap( r, spacing, off );
+
+ if ( !m_description.isEmpty() )
+ {
+ pp.begin( &off );
+ pp.fillRect( 0, 0, off.width(), off.height(), backg );
+
+ TQColor myColor = cg.color( TQColorGroup::Text ).light( 200 );
+ if ( qGray( myColor.rgb() ) == 0 )
+ myColor = TQColor( 100, 100, 110 );
+ pp.setPen( myColor );
+ pp.setPen( isSelected() ? cg.color( TQColorGroup::Mid ) : myColor );
+ pp.setFont( f2 );
+ pp.drawText( 0, 0, off.width(), off.height(), align, m_description );
+ pp.end();
+ if ( TQFontMetrics( f2 ).width( m_description ) > off.width() )
+ {
+ makeGradient( off, backg );
+ setToolTip( m_title + "
" + m_description );
+ }
+ if ( reverseLayout )
+ p->drawPixmap( width - off.width() - r, spacing + text_margin + f1h, off );
+ else
+ p->drawPixmap( r, spacing + text_margin + f1h, off );
+ }
+
+ if ( m_has_children )
+ {
+ TQImage i = right_triangle.convertToImage().smoothScale( right_triangle_size,
+ right_triangle_size );
+ TQPixmap 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, TQListView* parent)
+ : KMenuItem(nId, parent), lv(parent), cached_width( 0 )
+{
+ setEnabled(false);
+ left_margin = 15;
+}
+
+void KMenuItemSeparator::setup()
+{
+ KMenuItem::setup();
+
+ TQFont f = TQFont();
+ TQFontMetrics 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 TQString &text, const TQString &url )
+{
+ m_link_text = text;
+ m_link_url = url;
+ m_link_rect = TQRect();
+}
+
+bool KMenuItemSeparator::hitsLink( const TQPoint &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" ) );
+ TQImage i = pixmap.convertToImage().smoothScale( width - 15 - left_margin, pixmap.height() );
+ pixmap.convertFromImage( i );
+ cached_width = width;
+ }
+}
+
+void KMenuItemSeparator::paintCell(TQPainter* p, const TQColorGroup & 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 TQColorGroup::ColorRole crole = TQPalette::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;
+ }
+ TQFont f = listView()->font();
+ f.setWeight( TQFont::Normal );
+ f.setPointSize( 8 + KickerSettings::kickoffFontPointSizeOffset() );
+ p->setFont( f );
+ TQColor myColor = cg.color( TQColorGroup::Text ).light( 200 );
+ if ( qGray( myColor.rgb() ) == 0 )
+ myColor = TQColor( 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( TQColorGroup::Link ) );
+ f.setUnderline( true );
+ p->setFont( f );
+ p->drawText( pos, margin + 5,
+ width, h - ( margin +5 ), AlignTop, m_link_text );
+ m_link_rect = TQRect( 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 TQString& relPath, TQListView* parent)
+ : KMenuItemSeparator(nId, parent)
+{
+ setEnabled( false );
+ TQString 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);
+ TQStringList items = TQStringList::split( '/', relPath );
+ for ( TQStringList::ConstIterator it = items.begin(); it != items.end(); ++it )
+ {
+ path += *it + "/";
+ paths.append( "kicker:/goup/" + path );
+ KServiceGroup::Ptr subMenuRoot = KServiceGroup::group(path);
+ TQString 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();
+
+ TQFontMetrics fm( listView()->font() );
+ setHeight( QMAX( int( texts.count() * fm.height() + ( texts.count() + 1 ) * 2 + 10 ), height()) );
+ // nada
+}
+
+void KMenuItemHeader::paintCell(TQPainter* p, const TQColorGroup & cg, int , int width, int align )
+{
+ preparePixmap(width);
+
+ const BackgroundMode bgmode = listView()->viewport()->backgroundMode();
+ const TQColorGroup::ColorRole crole = TQPalette::backgroundRoleFromMode( bgmode );
+
+ TQBrush br = cg.brush( crole );
+ if ( isSelected() ) {
+ br = cg.brush( TQColorGroup::Highlight );
+ p->fillRect( 0, 0, width, height() - 3, br );
+ } else {
+ p->fillRect( 0, 0, width, height(), br );
+ }
+
+ TQFontMetrics 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() ) );
+
+ TQFont f1 = p->font();
+ f1.setPixelSize( title_font_pixelSize );
+ p->setFont( f1 );
+ int f1h = TQFontMetrics( f1 ).height();
+
+ p->setPen( cg.color( TQColorGroup::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( TQFont::DemiBold );
+ p->setFont( f1 );
+ f1h = TQFontMetrics( 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, TQListView* parent)
+ : KMenuItem(nId, parent)
+{
+ setEnabled(false);
+}
+
+void KMenuSpacer::setup()
+{
+ // nada
+}
+
+void KMenuSpacer::paintCell(TQPainter* p, const TQColorGroup & cg, int , int width, int )
+{
+ const BackgroundMode bgmode = listView()->viewport()->backgroundMode();
+ const TQColorGroup::ColorRole crole = TQPalette::backgroundRoleFromMode( bgmode );
+ TQBrush br = cg.brush( crole );
+
+ p->fillRect( 0, 0, width, height(), br );
+}
+
+void KMenuSpacer::setHeight( int i )
+{
+ KMenuItem::setHeight( i );
+}
+
+class ItemViewTip : public TQToolTip
+{
+public:
+ ItemViewTip( TQWidget *parent, TQListView *lv );
+
+ void maybeTip( const TQPoint &pos );
+
+private:
+ TQListView *view;
+
+};
+
+ItemViewTip::ItemViewTip( TQWidget *parent, TQListView *lv )
+ : TQToolTip( parent ), view( lv )
+{
+}
+
+void ItemViewTip::maybeTip( const TQPoint &pos )
+{
+ KMenuItem *item = dynamic_cast( view->itemAt( pos ) );
+ TQPoint contentsPos = view->viewportToContents( pos );
+ if ( !item )
+ return;
+
+ if ( item->toolTip().isNull() )
+ return;
+
+ TQRect 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(TQWidget* parent, const char* name)
+ : KListView(parent, name), m_spacer( 0 ),
+ m_mouseMoveSelects(true), m_iconSize(32)
+{
+ setHScrollBarMode( TQScrollView::AlwaysOff );
+ setFrameStyle( TQFrame::NoFrame );
+ setSelectionMode(TQListView::Single);
+ addColumn("");
+ header()->setStretchEnabled(1, 0);
+ //setColumnWidthMode(0, TQListView::Maximum);
+ header()->hide();
+ setMouseTracking(true);
+ setItemMargin(0);
+ setSorting(-1);
+ setTreeStepSize(38);
+ setFocusPolicy(TQWidget::NoFocus);
+
+ m_lastOne = 0;
+ m_old_contentY = -1;
+
+ connect(this, TQT_SIGNAL(mouseButtonClicked( int, TQListViewItem*, const TQPoint &, int )),
+ TQT_SLOT(slotItemClicked(int, TQListViewItem*, const TQPoint &, int)));
+
+ connect(this, TQT_SIGNAL(returnPressed(TQListViewItem*)), TQT_SLOT(slotItemClicked(TQListViewItem*)));
+ connect(this, TQT_SIGNAL(spacePressed(TQListViewItem*)), TQT_SLOT(slotItemClicked(TQListViewItem*)));
+
+ new ItemViewTip( viewport(), this );
+}
+
+KMenuItemHeader *ItemView::insertHeader(int id, const TQString &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 (TQListViewItemIterator it(this); it.current(); ++it)
+ {
+ if(static_cast(it.current())->id() == nId)
+ return static_cast(it.current());
+ }
+
+ return 0L;
+}
+
+bool ItemView::focusNextPrevChild(bool /*next*/)
+{
+ return false;
+}
+
+KMenuItem* ItemView::itemAtIndex(int nIndex)
+{
+ if(nIndex <= 0)
+ return 0L;
+
+ if(nIndex >= childCount())
+ return static_cast(lastItem());
+
+ int i = 1;
+ TQListViewItemIterator it(this);
+ for (;it.current(); ++i, ++it) {
+ if(i == nIndex)
+ return static_cast(it.current());
+ }
+
+ return static_cast(lastItem());
+}
+
+KMenuItem* ItemView::insertItem( const TQString& icon, const TQString& text, const TQString& description, const
+ TQString& 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 TQString& icon, const TQString& text, const TQString& description,
+ int nId, int nIndex, KMenuItem *parent)
+{
+ return insertItem( icon, text, description, TQString::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 TQString& 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;
+ TQListViewItemIterator it( this );
+ while ( it.current() ) {
+ if ( !dynamic_cast( it.current() ) && !it.current()->parent() && it.current()->isVisible() ) {
+ it.current()->invalidateHeight();
+ item_height += it.current()->totalHeight();
+ }
+ ++it;
+ }
+
+ if ( height() > item_height )
+ m_spacer->setHeight( height() - item_height );
+ else
+ m_spacer->setHeight( 0 );
+}
+
+KMenuItem *ItemView::insertMenuItem(KService::Ptr& s, int nId, int nIndex, KMenuItem* parentItem,
+ const TQString& aliasname, const TQString & label, const TQString & categoryIcon )
+{
+ if (!s)
+ return 0;
+
+ TQString 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 TQString& s, int nId, int nIndex, const TQStringList* /*suppressGenericNames*/,
+ const TQString& /*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 TQString& 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
+ TQString name=f.readName();
+ if (name.isEmpty())
+ name=f.readURL();
+
+ newItem->setTitle(name);
+
+ TQString 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 TQString& icon, const TQString& caption, const TQString& description, const TQString& 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, TQListViewItem * item, const TQPoint & /*pos*/, int /*c*/ )
+{
+ if (button==1)
+ slotItemClicked(item);
+}
+
+void ItemView::slotItemClicked(TQListViewItem* item)
+{
+ KMenuItem* kitem = dynamic_cast(item);
+ if ( !kitem )
+ return;
+
+ if(kitem->service()) {
+ emit startService(kitem->service());
+ }
+ else if(!kitem->path().isEmpty()) {
+ emit startURL(kitem->path());
+ }
+}
+
+void ItemView::contentsMousePressEvent ( TQMouseEvent * e )
+{
+ KListView::contentsMousePressEvent( e );
+
+ TQPoint vp = contentsToViewport(e->pos());
+ KMenuItemSeparator *si = dynamic_cast( itemAt( vp ) );
+ if ( si )
+ {
+ if ( si->hitsLink( vp - itemRect(si).topLeft() ) )
+ emit startURL( si->linkUrl() );
+ }
+}
+
+void ItemView::contentsMouseMoveEvent(TQMouseEvent *e)
+{
+ TQPoint vp = contentsToViewport(e->pos());
+ TQListViewItem * i = itemAt( vp );
+
+ bool link_cursor = false;
+ KMenuItemSeparator *si = dynamic_cast( i );
+ if ( si )
+ link_cursor = si->hitsLink( vp - itemRect(si).topLeft() );
+
+ if (i && !i->isSelectable() && !link_cursor) {
+ unsetCursor();
+ viewport()->unsetCursor();
+ return;
+ }
+
+ KListView::contentsMouseMoveEvent(e);
+
+ if (m_mouseMoveSelects) {
+ if(i && i->isEnabled() && !i->isSelected() &&
+ // FIXME: This is wrong if you drag over the items.
+ (e->state() & (LeftButton|MidButton|RightButton)) == 0)
+ KListView::setSelected(i, true);
+ else if (!i && selectedItem())
+ KListView::setSelected(selectedItem(), false);
+ }
+
+ if ( link_cursor )
+ setCursor( Qt::PointingHandCursor );
+ else
+ unsetCursor();
+
+}
+
+void ItemView::leaveEvent(TQEvent* e)
+{
+ KListView::leaveEvent(e);
+
+ clearSelection();
+}
+
+void ItemView::resizeEvent ( TQResizeEvent * e )
+{
+ KListView::resizeEvent( e );
+// if ( m_lastOne )
+// int diff = itemRect( m_lastOne ).bottom() - viewport()->height();
+}
+
+void ItemView::viewportPaintEvent ( TQPaintEvent * 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 = TQString::null;
+}
+
+void ItemView::contentsWheelEvent(TQWheelEvent *e)
+{
+ KListView::contentsWheelEvent(e);
+
+ TQPoint vp = contentsToViewport(e->pos());
+ TQListViewItem * 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);
+}
+
+TQDragObject * ItemView::dragObject()
+{
+ KMultipleDrag* o = 0;
+ TQListViewItem *item = itemAt( viewport()->mapFromGlobal(TQCursor::pos()) );
+ if ( item ) {
+ KMenuItem* kitem = static_cast(item);
+
+ if (dynamic_cast(item))
+ return 0;
+
+ o = new KMultipleDrag(viewport());
+ TQPixmap pix = KGlobal::iconLoader()->loadIcon( kitem->icon(), KIcon::Panel, m_iconSize);
+ TQPixmap add = KGlobal::iconLoader()->loadIcon( "add", KIcon::Small );
+
+ TQPainter p( &pix );
+ p.drawPixmap(pix.height()-add.height(), pix.width()-add.width(), add);
+ p.end();
+
+ TQBitmap 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.
+ TQString 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:/")) {
+ TQString uri = kitem->path();
+
+ if (uri.startsWith(locateLocal("data", TQString::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;
+ TQListViewItemIterator it( this );
+ while ( it.current() ) {
+ if ( !dynamic_cast( it.current() ) && !it.current()->parent() && it.current()->isVisible() ) {
+ item_height += it.current()->height();
+ }
+ ++it;
+ }
+
+ return item_height;
+}
+
+
+KMenuItemDrag::KMenuItemDrag(KMenuItem& item, TQWidget *dragSource)
+ : TQDragObject(dragSource, 0)
+{
+ TQBuffer buff(a);
+ buff.open(IO_WriteOnly);
+ TQDataStream s(&buff);
+
+ s << item.id() << (item.service() ? item.service()->storageId() : TQString::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;
+}
+
+TQByteArray KMenuItemDrag::encodedData(const char* mimeType) const
+{
+ if (TQString("application/kmenuitem") == mimeType)
+ return a;
+
+ return TQByteArray();
+}
+
+bool KMenuItemDrag::canDecode(const TQMimeSource * e)
+{
+ if (e->provides( "application/kmenuitem" ) )
+ return true;
+
+ return false;
+}
+
+bool ItemView::acceptDrag (TQDropEvent* event) const
+{
+ if ( !acceptDrops() )
+ return false;
+
+ if (KMenuItemDrag::canDecode(event))
+ return true;
+
+ if (TQTextDrag::canDecode(event)) {
+ TQString text;
+ TQTextDrag::decode(event,text);
+ return !text.startsWith("programs:/");
+ }
+
+ return itemsMovable();
+}
+
+bool KMenuItemDrag::decode(const TQMimeSource* e, KMenuItemInfo& item)
+{
+ TQByteArray a = e->encodedData("application/kmenuitem");
+
+ if (a.isEmpty()) {
+ TQStringList l;
+ bool ret = TQUriDrag::decodeToUnicodeUris( e, l );
+ if ( ret )
+ {
+ for ( TQStringList::ConstIterator it = l.begin(); it != l.end(); ++it )
+ {
+ TQString 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;
+ }
+
+ TQBuffer buff(a);
+ buff.open(IO_ReadOnly);
+ TQDataStream s(&buff);
+
+ KMenuItemInfo i;
+ TQString 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(TQWidget* parent, const char* name)
+ : ItemView(parent, name)
+{
+}
+
+bool FavoritesItemView::acceptDrag (TQDropEvent* event) const
+{
+ if (event->source()==this->viewport())
+ return true;
+
+ if (KMenuItemDrag::canDecode(event)) {
+ KMenuItemInfo item;
+ KMenuItemDrag::decode(event,item);
+ TQStringList favs = KickerSettings::favorites();
+
+ if (item.m_s)
+ return favs.find(item.m_s->storageId())==favs.end();
+ else {
+ TQStringList::Iterator it;
+
+ TQString uri = item.m_path;
+
+ if (uri.startsWith(locateLocal("data", TQString::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://",TQString::null)==uri)
+ break;
+ }
+ }
+ return it==favs.end();
+ }
+ }
+
+ if (TQTextDrag::canDecode(event)) {
+ TQString text;
+ TQTextDrag::decode(event,text);
+ TQStringList favs = KickerSettings::favorites();
+
+ if (text.endsWith(".desktop")) {
+ KService::Ptr p = KService::serviceByDesktopPath(text.replace("file://",TQString::null));
+ return (p && favs.find(p->storageId())==favs.end());
+ }
+ else {
+ TQStringList::Iterator it;
+ for (it = favs.begin(); it != favs.end(); ++it) {
+ if ((*it)[0]=='/') {
+ KDesktopFile df((*it),true);
+ if (df.readURL().replace("file://",TQString::null)==text)
+ break;
+ }
+ }
+ return it==favs.end();
+ }
+ }
+
+ return itemsMovable();
+}
+
+#include "itemview.moc"
+
+// vim:cindent:sw=4:
diff --git a/kicker/kicker/ui/itemview.h b/kicker/kicker/ui/itemview.h
new file mode 100644
index 000000000..c8b95ee42
--- /dev/null
+++ b/kicker/kicker/ui/itemview.h
@@ -0,0 +1,260 @@
+/*****************************************************************
+
+Copyright (c) 1996-2000 the kicker authors. See file AUTHORS.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#ifndef __itemview_h__
+#define __itemview_h__
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "kmenubase.h"
+#include "kmenuitembase.h"
+#include "service_mnu.h"
+
+class KickerClientMenu;
+class KBookmarkMenu;
+class KActionCollection;
+class KBookmarkOwner;
+class Panel;
+class TQWidgetStack;
+class KHistoryCombo;
+class TQScrollView;
+class PopupMenuTitle;
+class TQWidget;
+class TQVBoxLayout;
+class TQTimer;
+class KPixmap;
+
+class KMenuItem : public TQListViewItem
+{
+public:
+ KMenuItem(int nId, TQListView* parent) : TQListViewItem(parent), m_id(nId) { init(); }
+ KMenuItem(int nId, TQListViewItem* parent) : TQListViewItem(parent), m_id(nId) { init(); }
+ ~KMenuItem();
+
+ void setIcon(const TQString& icon, int size);
+ TQString icon() const { return m_icon; }
+ void setTitle( const TQString& text );
+ TQString title() const { return m_title; }
+ void setToolTip( const TQString& text );
+ TQString toolTip() const { return m_tooltip; }
+ void setDescription(const TQString& text);
+ TQString description() const { return m_description; }
+ void setService(KService::Ptr& s) { m_s = s; }
+ KService::Ptr service() { return m_s; }
+ void setPath(const TQString& u) { m_path = u; }
+ TQString path() const { return m_path; }
+ void setMenuPath(const TQString& u) { m_menuPath = u; }
+ TQString 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 TQColor& c);
+
+protected:
+ virtual void paintCell(TQPainter* p, const TQColorGroup & cg, int column, int width, int align);
+ virtual void paintCellInter(TQPainter* p, const TQColorGroup & cg, int column, int width, int align);
+ virtual void setup();
+
+private:
+ void init();
+
+ int m_id;
+ KService::Ptr m_s;
+ TQString m_title;
+ TQString m_description;
+ TQString m_path;
+ TQString m_icon;
+ TQString m_tooltip;
+ TQString m_menuPath;
+ float title_font_size;
+ float description_font_size;
+ bool m_has_children;
+ int m_old_width;
+ TQPixmap right_triangle;
+};
+
+class KMenuItemSeparator : public KMenuItem
+{
+public:
+ KMenuItemSeparator(int nId, TQListView* parent);
+ virtual void setup();
+
+ virtual void paintCell(TQPainter* p, const TQColorGroup & cg, int column, int width, int align);
+ void setLink(const TQString &text, const TQString &link = TQString::null );
+
+ TQString linkUrl() const { return m_link_url; }
+
+ /// returns true if the cursor has to change
+ bool hitsLink(const TQPoint &pos);
+
+protected:
+ void preparePixmap(int width);
+ TQPixmap pixmap;
+ int left_margin;
+
+private:
+ TQListView* lv;
+ int cached_width;
+ TQString m_link_text, m_link_url;
+ TQRect m_link_rect;
+
+};
+
+class KMenuItemHeader : public KMenuItemSeparator
+{
+public:
+ KMenuItemHeader( int nId, const TQString &relpath, TQListView* parent);
+ virtual void setup();
+
+ virtual void paintCell(TQPainter* p, const TQColorGroup & cg, int column, int width, int align);
+
+private:
+ TQListView* lv;
+ TQStringList paths;
+ TQStringList texts;
+ TQStringList icons;
+ TQPixmap left_triangle;
+};
+
+class KMenuSpacer : public KMenuItem
+{
+public:
+ KMenuSpacer(int nId, TQListView* parent);
+ virtual void paintCell(TQPainter* p, const TQColorGroup & cg, int column, int width, int align);
+ virtual void setup();
+
+ void setHeight(int);
+};
+
+class ItemView : public KListView
+{
+ friend class KMenuItem;
+
+ Q_OBJECT
+public:
+ ItemView(TQWidget* parent, const char* name = 0);
+
+ KMenuItem* insertItem( const TQString& icon, const TQString& text, const TQString& description, int nId, int nIndex, KMenuItem* parentItem = 0 );
+ KMenuItem* insertItem( const TQString& icon, const TQString& text, const TQString& description, const TQString& path, int nId, int nIndex, KMenuItem* parentItem = 0 );
+ int insertItem( PopupMenuTitle*, int, int);
+ int setItemEnabled(int id, bool enabled);
+ KMenuItemSeparator *insertSeparator(int id, const TQString& text, int nIndex);
+ KMenuItemHeader *insertHeader(int id, const TQString &relpath);
+ KMenuItem* insertMenuItem(KService::Ptr & s, int nId, int nIndex = -1, KMenuItem* parentItem = 0,
+ const TQString &aliasname = TQString::null, const TQString &label = TQString::null,
+ const TQString &categoryIcon = TQString::null);
+ KMenuItem* insertRecentlyItem(const TQString& s, int nId, int nIndex = -1);
+ KMenuItem* insertDocumentItem(const TQString& s, int nId, int nIndex = -1 , const TQStringList* suppressGenericNames = 0,
+ const TQString& aliasname = TQString::null);
+ KMenuItem* insertSubItem(const TQString& icon, const TQString& caption, const TQString& description, const TQString& 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();
+ TQString path;
+ void setBackPath( const TQString &str ) { m_back_url = str; }
+ TQString backPath() const { return m_back_url; }
+
+public slots:
+ void slotItemClicked(TQListViewItem*);
+ void slotMoveContent();
+
+signals:
+ void startService(KService::Ptr kservice);
+ void startURL(const TQString& u);
+
+protected:
+ void contentsMouseMoveEvent(TQMouseEvent *e);
+ void contentsMousePressEvent ( TQMouseEvent * e );
+ void contentsWheelEvent(TQWheelEvent *e);
+ void leaveEvent(TQEvent *e);
+ virtual void resizeEvent ( TQResizeEvent * e );
+ virtual void viewportPaintEvent ( TQPaintEvent * pe );
+ virtual TQDragObject* dragObject ();
+ virtual bool acceptDrag (TQDropEvent* event) const;
+ virtual bool focusNextPrevChild(bool next);
+
+private slots:
+ void slotItemClicked(int button, TQListViewItem * item, const TQPoint & pos, int c );
+
+private:
+ KMenuItem* itemAtIndex(int nIndex);
+ void moveItemToIndex(KMenuItem*, int);
+
+ TQWidget* m_itemBox;
+ TQVBoxLayout* m_itemLayout;
+ KMenuItem *m_lastOne;
+ KMenuSpacer *m_spacer;
+
+ TQString m_back_url;
+
+ bool m_mouseMoveSelects;
+ int m_iconSize;
+ int m_old_contentY;
+};
+
+class FavoritesItemView : public ItemView
+{
+public:
+ FavoritesItemView(TQWidget* parent, const char* name = 0);
+
+protected:
+ virtual bool acceptDrag (TQDropEvent* event) const;
+};
+
+class KMenuItemInfo
+{
+public:
+ int m_id;
+ KService::Ptr m_s;
+ TQString m_title;
+ TQString m_description;
+ TQString m_path;
+ TQString m_icon;
+};
+
+class KMenuItemDrag : public TQDragObject
+{
+ public:
+ KMenuItemDrag(KMenuItem& item, TQWidget *dragSource);
+ ~KMenuItemDrag();
+
+ virtual const char * format(int i = 0) const;
+ virtual TQByteArray encodedData(const char *) const;
+
+ static bool canDecode(const TQMimeSource * e);
+ static bool decode(const TQMimeSource* e, KMenuItemInfo& item);
+
+ private:
+ TQByteArray a;
+};
+
+#endif
diff --git a/kicker/kicker/ui/k_mnu_stub.cpp b/kicker/kicker/ui/k_mnu_stub.cpp
new file mode 100644
index 000000000..b02d2bcbf
--- /dev/null
+++ b/kicker/kicker/ui/k_mnu_stub.cpp
@@ -0,0 +1,141 @@
+/*****************************************************************
+
+Copyright (c) 2006 Dirk Mueller
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#include "k_mnu_stub.h"
+#include "k_new_mnu.h"
+#include "k_mnu.h"
+
+void KMenuStub::removeClientMenu(int id)
+{
+ if(m_type == t_KMenu)
+ return m_w.kmenu->removeClientMenu(id);
+ return m_w.panelkmenu->removeClientMenu(id);
+}
+
+int KMenuStub::insertClientMenu(KickerClientMenu *p)
+{
+ if(m_type == t_KMenu)
+ return m_w.kmenu->insertClientMenu(p);
+ return m_w.panelkmenu->insertClientMenu(p);
+}
+
+void KMenuStub::adjustSize()
+{
+ if(m_type == t_KMenu)
+ return m_w.kmenu->adjustSize();
+ return m_w.panelkmenu->adjustSize();
+}
+
+void KMenuStub::hide()
+{
+ if(m_type == t_KMenu)
+ return m_w.kmenu->hide();
+ return m_w.panelkmenu->hide();
+}
+
+void KMenuStub::show()
+{
+ if(m_type == t_KMenu)
+ return m_w.kmenu->show();
+ return m_w.panelkmenu->show();
+}
+
+void KMenuStub::showMenu()
+{
+ if(m_type == t_KMenu)
+ return m_w.kmenu->showMenu();
+ return m_w.panelkmenu->showMenu();
+}
+
+#if 0
+void KMenuStub::resize()
+{
+ if(m_type == t_KMenu)
+ return m_w.kmenu->resize();
+ return m_w.panelkmenu->resize();
+}
+#endif
+
+void KMenuStub::popup(const TQPoint &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);
+}
+
+TQSize KMenuStub::sizeHint() const
+{
+ if(m_type == t_KMenu)
+ return m_w.kmenu->sizeHint();
+ return m_w.panelkmenu->sizeHint();
+}
+
+bool KMenuStub::highlightMenuItem( const TQString &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();
+}
+
+TQWidget* KMenuStub::widget()
+{
+ if(m_type == t_KMenu)
+ return m_w.kmenu;
+ return m_w.panelkmenu;
+}
+
diff --git a/kicker/kicker/ui/k_mnu_stub.h b/kicker/kicker/ui/k_mnu_stub.h
new file mode 100644
index 000000000..362d132b2
--- /dev/null
+++ b/kicker/kicker/ui/k_mnu_stub.h
@@ -0,0 +1,72 @@
+/*****************************************************************
+
+Copyright (c) 2006 Dirk Mueller
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#ifndef __k_mnu_stub_h__
+#define __k_mnu_stub_h__
+
+#include
+#include
+
+class KickerClientMenu;
+class KMenu;
+class PanelKMenu;
+
+
+
+
+class KMenuStub
+{
+public:
+ KMenuStub(KMenu* _kmenu)
+ : m_type(t_KMenu) { m_w.kmenu = _kmenu; }
+ KMenuStub(PanelKMenu* _panelkmenu)
+ : m_type(t_PanelKMenu) { m_w.panelkmenu = _panelkmenu; }
+ ~KMenuStub() {}
+
+ void removeClientMenu(int id);
+ int insertClientMenu(KickerClientMenu *p);
+ void adjustSize();
+ void hide();
+ void show();
+ void showMenu();
+ void resize();
+ void popup(const TQPoint &pos, int indexAtPoint = -1);
+ void selectFirstItem();
+ void resize(int, int);
+ TQSize sizeHint() const;
+ bool highlightMenuItem( const TQString &menuId );
+ void clearRecentMenuItems();
+ void initialize();
+
+ TQWidget* widget();
+
+ bool isVisible() const;
+private:
+ enum {t_PanelKMenu, t_KMenu} m_type;
+ union {
+ KMenu* kmenu;
+ PanelKMenu* panelkmenu;
+ } m_w;
+};
+
+#endif
diff --git a/kicker/kicker/ui/k_new_mnu.cpp b/kicker/kicker/ui/k_new_mnu.cpp
new file mode 100644
index 000000000..34b11790b
--- /dev/null
+++ b/kicker/kicker/ui/k_new_mnu.cpp
@@ -0,0 +1,3779 @@
+/*****************************************************************
+
+ Copyright (c) 1996-2000 the kicker authors. See file AUTHORS.
+ Copyright (c) 2006 Debajyoti Bera
+ Copyright (c) 2006 Dirk Mueller
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+******************************************************************/
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "client_mnu.h"
+#include "container_base.h"
+#include "global.h"
+#include "knewbutton.h"
+#include "kicker.h"
+#include "kickerSettings.h"
+#include "konqbookmarkmanager.h"
+#include "menuinfo.h"
+#include "menumanager.h"
+#include "popupmenutitle.h"
+#include "quickbrowser_mnu.h"
+#include "recentapps.h"
+#include "flipscrollview.h"
+#include "itemview.h"
+#include
+#include
+#include
+
+#include "media_watcher.h"
+#include "k_mnu.h"
+#include "k_new_mnu.h"
+#include "k_new_mnu.moc"
+#include "kickoff_bar.h"
+
+#define WAIT_BEFORE_QUERYING 700
+
+#define IDS_PER_CATEGORY 20
+#define ACTIONS_ID_BASE 10
+#define APP_ID_BASE 10 + IDS_PER_CATEGORY
+#define BOOKMARKS_ID_BASE 10 + (IDS_PER_CATEGORY * 2)
+#define NOTES_ID_BASE 10 + (IDS_PER_CATEGORY * 3)
+#define MAIL_ID_BASE 10 + (IDS_PER_CATEGORY * 4)
+#define FILE_ID_BASE 10 + (IDS_PER_CATEGORY * 5)
+#define MUSIC_ID_BASE 10 + (IDS_PER_CATEGORY * 6)
+#define WEBHIST_ID_BASE 10 + (IDS_PER_CATEGORY * 7)
+#define CHAT_ID_BASE 10 + (IDS_PER_CATEGORY * 8)
+#define FEED_ID_BASE 10 + (IDS_PER_CATEGORY * 9)
+#define PIC_ID_BASE 10 + (IDS_PER_CATEGORY * 10)
+#define VIDEO_ID_BASE 10 + (IDS_PER_CATEGORY * 11)
+#define DOC_ID_BASE 10 + (IDS_PER_CATEGORY * 12)
+#define OTHER_ID_BASE 10 + (IDS_PER_CATEGORY * 13)
+
+static TQString calculate(const TQString &exp)
+{
+ TQString result, cmd;
+ const TQString bc = KStandardDirs::findExe("bc");
+ if ( !bc.isEmpty() )
+ cmd = TQString("echo %1 | %2").arg(KProcess::quote(exp), KProcess::quote(bc));
+ else
+ cmd = TQString("echo $((%1))").arg(exp);
+ FILE *fs = popen(TQFile::encodeName(cmd).data(), "r");
+ if (fs)
+ {
+ TQTextStream ts(fs, IO_ReadOnly);
+ result = ts.read().stripWhiteSpace();
+ pclose(fs);
+ }
+ return result;
+}
+
+static TQString workaroundStringFreeze(const TQString& str)
+{
+ TQString s = str;
+
+ s.replace("","&");
+ TQRegExp re("<[^>]+>");
+ re.setMinimal(true);
+ re.setCaseSensitive(false);
+
+ s.replace(re, "");
+ s = s.simplifyWhiteSpace();
+
+ return s;
+}
+
+int base_category_id[] = {ACTIONS_ID_BASE, APP_ID_BASE, BOOKMARKS_ID_BASE, NOTES_ID_BASE, MAIL_ID_BASE,
+ FILE_ID_BASE, MUSIC_ID_BASE, WEBHIST_ID_BASE, CHAT_ID_BASE, FEED_ID_BASE,
+ PIC_ID_BASE, VIDEO_ID_BASE, DOC_ID_BASE, OTHER_ID_BASE};
+
+#include
+
+static int used_size( TQLabel *label, int oldsize )
+{
+ TQSimpleRichText 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(TQString::null), m_orientation(UnDetermined), m_search_plugin( 0 )
+{
+ setMouseTracking(true);
+ connect(&m_sloppyTimer, TQT_SIGNAL(timeout()), TQT_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(), TQT_SIGNAL(configurationChanged()),
+ this, TQT_SLOT(configChanged()));
+
+ KUser * user = new KUser();
+
+ char hostname[256];
+ hostname[0] = '\0';
+ if (!gethostname( hostname, sizeof(hostname) ))
+ hostname[sizeof(hostname)-1] = '\0';
+
+ m_userInfo->setText( i18n( "User %1 on %2" )
+ .arg( user->loginName() ).arg( hostname ) );
+ setupUi();
+
+ m_userInfo->setBackgroundMode( PaletteBase );
+ TQColor userInfoColor = TQApplication::palette().color( TQPalette::Normal, TQColorGroup::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, TQT_SIGNAL(tabClicked(TQTab*)), TQT_SLOT(tabClicked(TQTab*)));
+
+ const int tab_icon_size = 32;
+
+ m_tabs[FavoriteTab] = new TQTab;
+ m_tabBar->addTab(m_tabs[FavoriteTab]);
+ m_tabBar->setToolTip(FavoriteTab, "" + i18n( "Most commonly used applications and documents" ) + "" );
+ m_tabs[ApplicationsTab] = new TQTab;
+ m_tabBar->addTab(m_tabs[ApplicationsTab]);
+ m_tabBar->setToolTip(ApplicationsTab, "" + i18n( "List of installed applications" ) +
+ "" );
+
+ m_tabs[ComputerTab] = new TQTab;
+ m_tabBar->addTab(m_tabs[ComputerTab]);
+ m_tabBar->setToolTip(ComputerTab, "" + i18n( "Information and configuration of your "
+ "system, access to personal files, network resources and connected disk drives")
+ + "");
+#if 0
+ m_tabs[SearchTab] = new TQTab;
+ m_tabBar->addTab(m_tabs[SearchTab]);
+#endif
+ m_tabs[HistoryTab] = new TQTab;
+ m_tabBar->addTab(m_tabs[HistoryTab]);
+ m_tabBar->setToolTip(HistoryTab, "" + i18n( "Recently used applications and documents" ) +
+ "" );
+ m_tabs[LeaveTab] = new TQTab;
+ m_tabBar->addTab(m_tabs[LeaveTab]);
+ m_tabBar->setToolTip(LeaveTab, i18n("Logout, switch user, switch off or reset,"
+ " suspend of the system" ) + "" );
+
+ if (KickerSettings::kickoffTabBarFormat() != KickerSettings::IconOnly) {
+ m_tabs[FavoriteTab]->setText(workaroundStringFreeze(i18n(" Favorites
")));
+ m_tabs[HistoryTab]->setText(workaroundStringFreeze(i18n("History
")));
+ m_tabs[ComputerTab]->setText(
+ workaroundStringFreeze(i18n(" Computer
")));
+ m_tabs[ApplicationsTab]->setText(workaroundStringFreeze(i18n("Applications
")));
+ m_tabs[LeaveTab]->setText(
+ workaroundStringFreeze(i18n("Leave
")));
+ }
+
+ if (KickerSettings::kickoffTabBarFormat() != KickerSettings::LabelOnly) {
+ m_tabs[FavoriteTab]->setIconSet(BarIcon("bookmark", tab_icon_size));
+ m_tabs[HistoryTab]->setIconSet(BarIcon("recently_used", tab_icon_size));
+ m_tabs[ComputerTab]->setIconSet(BarIcon("system", tab_icon_size));
+ m_tabs[ApplicationsTab]->setIconSet(BarIcon("player_playlist", tab_icon_size));
+ m_tabs[LeaveTab]->setIconSet(BarIcon("leave", tab_icon_size));
+ }
+
+ connect(m_tabBar, TQT_SIGNAL(selected(int)), m_stacker, TQT_SLOT(raiseWidget(int)));
+ connect(m_stacker, TQT_SIGNAL(aboutToShow(int)), m_tabBar, TQT_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, TQT_SIGNAL( backButtonClicked() ), TQT_SLOT( slotGoBack() ) );
+
+ m_exitView = new FlipScrollView(m_stacker, "m_exitView");
+ m_stacker->addWidget(m_exitView, LeaveTab);
+ connect( m_exitView, TQT_SIGNAL( backButtonClicked() ), TQT_SLOT( slotGoExitMainMenu() ) );
+
+ m_searchWidget = new TQVBox (m_stacker, "m_searchWidget");
+ m_searchWidget->setSpacing(0);
+ m_stacker->addWidget(m_searchWidget, 5);
+
+ // search provider icon
+ TQPixmap icon;
+ KURIFilterData data;
+ TQStringList list;
+ data.setData( TQString("some keyword") );
+ list << "kurisearchfilter" << "kuriikwsfilter";
+
+ if ( KURIFilter::self()->filterURI(data, list) ) {
+ TQString iconPath = locate("cache", KMimeType::favIconForURL(data.uri()) + ".png");
+ if ( iconPath.isEmpty() )
+ icon = SmallIcon("enhanced_browsing");
+ else
+ icon = TQPixmap( 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(TQWidget::NoFocus);
+ m_searchActions->setItemMargin(4);
+ m_searchInternet = new TQListViewItem(m_searchActions, i18n("Search Internet"));
+ m_searchInternet->setPixmap(0,icon);
+ setTabOrder(m_kcommand, m_searchResultsWidget);
+
+ m_kerryInstalled = !KStandardDirs::findExe(TQString::fromLatin1("kerry")).isEmpty();
+ m_isShowing = false;
+
+ if (!m_kerryInstalled) {
+ m_searchIndex = 0;
+ m_searchActions->setMaximumHeight(5+m_searchInternet->height());
+ }
+ else {
+ m_searchIndex = new TQListViewItem(m_searchActions, i18n("Search Index"));
+ m_searchIndex->setPixmap(0,SmallIcon("kerry"));
+ m_searchActions->setMaximumHeight(5+m_searchIndex->height()*2);
+ }
+ connect(m_searchActions, TQT_SIGNAL(clicked(TQListViewItem*)), TQT_SLOT(searchActionClicked(TQListViewItem*)));
+ connect(m_searchActions, TQT_SIGNAL(returnPressed(TQListViewItem*)), TQT_SLOT(searchActionClicked(TQListViewItem*)));
+ connect(m_searchActions, TQT_SIGNAL(spacePressed(TQListViewItem*)), TQT_SLOT(searchActionClicked(TQListViewItem*)));
+
+ connect(m_searchResultsWidget, TQT_SIGNAL(startService(KService::Ptr)), TQT_SLOT(slotStartService(KService::Ptr)));
+ connect(m_searchResultsWidget, TQT_SIGNAL(startURL(const TQString&)), TQT_SLOT(slotStartURL(const TQString&)));
+ connect(m_searchResultsWidget, TQT_SIGNAL(rightButtonPressed( TQListViewItem*, const TQPoint &, int )), TQT_SLOT(slotContextMenuRequested( TQListViewItem*, const TQPoint &, int )));
+
+ connect(m_recentlyView, TQT_SIGNAL(startService(KService::Ptr)), TQT_SLOT(slotStartService(KService::Ptr)));
+ connect(m_recentlyView, TQT_SIGNAL(startURL(const TQString&)), TQT_SLOT(slotStartURL(const TQString&)));
+ connect(m_recentlyView, TQT_SIGNAL(rightButtonPressed( TQListViewItem*, const TQPoint &, int )), TQT_SLOT(slotContextMenuRequested( TQListViewItem*, const TQPoint &, int )));
+
+ connect(m_favoriteView, TQT_SIGNAL(startService(KService::Ptr)), TQT_SLOT(slotStartService(KService::Ptr)));
+ connect(m_favoriteView, TQT_SIGNAL(startURL(const TQString&)), TQT_SLOT(slotStartURL(const TQString&)));
+ connect(m_favoriteView, TQT_SIGNAL(rightButtonPressed( TQListViewItem*, const TQPoint &, int )), TQT_SLOT(slotContextMenuRequested( TQListViewItem*, const TQPoint &, int )));
+ connect(m_favoriteView, TQT_SIGNAL(moved(TQListViewItem*, TQListViewItem*, TQListViewItem*)), TQT_SLOT(slotFavoritesMoved( TQListViewItem*, TQListViewItem*, TQListViewItem* )));
+
+ connect(m_systemView, TQT_SIGNAL(startURL(const TQString&)), TQT_SLOT(slotStartURL(const TQString&)));
+ connect(m_systemView, TQT_SIGNAL(startService(KService::Ptr)), TQT_SLOT(slotStartService(KService::Ptr)));
+ connect(m_systemView, TQT_SIGNAL(rightButtonPressed( TQListViewItem*, const TQPoint &, int )), TQT_SLOT(slotContextMenuRequested( TQListViewItem*, const TQPoint &, int )));
+
+ connect(m_browserView, TQT_SIGNAL(startURL(const TQString&)), TQT_SLOT(slotGoSubMenu(const TQString&)));
+ connect(m_browserView, TQT_SIGNAL(startService(KService::Ptr)), TQT_SLOT(slotStartService(KService::Ptr)));
+ connect(m_browserView, TQT_SIGNAL(rightButtonPressed( TQListViewItem*, const TQPoint &, int )), TQT_SLOT(slotContextMenuRequested( TQListViewItem*, const TQPoint &, int )));
+
+ connect(m_exitView, TQT_SIGNAL(startURL(const TQString&)), TQT_SLOT(slotStartURL(const TQString&)));
+ connect(m_exitView, TQT_SIGNAL(rightButtonPressed( TQListViewItem*, const TQPoint &, int )), TQT_SLOT(slotContextMenuRequested( TQListViewItem*, const TQPoint &, int )));
+
+ m_kcommand->setDuplicatesEnabled( false );
+ m_kcommand->setLineEdit(new KLineEdit(m_kcommand, "m_kcommand-lineedit"));
+ m_kcommand->setCompletionMode( KGlobalSettings::CompletionAuto );
+ connect(m_kcommand, TQT_SIGNAL(cleared()), TQT_SLOT(clearedHistory()));
+ connect(m_kcommand->lineEdit(), TQT_SIGNAL(returnPressed()), TQT_SLOT(searchAccept()));
+ connect(m_kcommand->lineEdit(), TQT_SIGNAL(textChanged(const TQString &)), TQT_SLOT(searchChanged(const TQString &)));
+
+ // 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 TQTimer (this, "input_timer");
+ connect( input_timer, TQT_SIGNAL(timeout()), this, TQT_SLOT(doQuery()) );
+
+ init_search_timer = new TQTimer (this, "init_search_timer");
+ connect( init_search_timer, TQT_SIGNAL(timeout()), this, TQT_SLOT(initSearch()) );
+ init_search_timer->start(2000, true);
+
+ connect( m_favoriteView, TQT_SIGNAL( dropped (TQDropEvent *, TQListViewItem * ) ),
+ TQT_SLOT( slotFavDropped( TQDropEvent *, TQListViewItem * ) ) );
+
+ 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 = TQRegExp("^([\\w\\-]+\\.)*[\\w\\-]+@([\\w\\-]+\\.)*[\\w\\-]+$");
+ authRegExp = TQRegExp("^[a-zA-Z]+://\\w+(:\\w+)?@([\\w\\-]+\\.)*[\\w\\-]+(:\\d+)?(/.*)?$");
+ uriRegExp = TQRegExp("^[a-zA-Z]+://([\\w\\-]+\\.)*[\\w\\-]+(:\\d+)?(/.*)?$");
+ uri2RegExp = TQRegExp("^([\\w\\-]+\\.)+[\\w\\-]+(:\\d+)?(/.*)?$");
+
+ m_resizeHandle = new TQLabel(this);
+ m_resizeHandle->setBackgroundOrigin( TQLabel::ParentOrigin );
+ m_resizeHandle->setScaledContents(true);
+ m_resizeHandle->setFixedSize( 16, 16 );
+ m_searchFrame->stackUnder( m_resizeHandle );
+ m_isresizing = false;
+
+ m_searchPixmap->setPixmap( BarIcon( "find", 32 ) );
+
+ TQFont f = font();
+ f.setPointSize( kMax( 7, (f.pointSize() * 4 / 5 ) + KickerSettings::kickoffFontPointSizeOffset() ) );
+ m_tabBar->setFont ( f );
+ f.setPointSize( kMax( 7, (f.pointSize() * 3 / 2 ) + KickerSettings::kickoffFontPointSizeOffset() ) );
+ m_searchLabel->setFont( f );
+
+ static_cast(m_kcommand->lineEdit())->setClickMessage(i18n( "Applications, Contacts and Documents" ) );
+
+ bookmarkManager = 0;
+ m_addressBook = 0;
+ m_popupMenu = 0;
+
+ main_border_tl.load( locate("data", "kicker/pics/main_corner_tl.png" ) );
+ main_border_tr.load( locate("data", "kicker/pics/main_corner_tr.png" ) );
+
+ search_tab_left.load( locate("data", "kicker/pics/search-tab-left.png" ) );
+ search_tab_right.load( locate("data", "kicker/pics/search-tab-right.png" ) );
+ search_tab_center.load( locate("data", "kicker/pics/search-tab-center.png" ) );
+
+ search_tab_top_left.load( locate("data", "kicker/pics/search-tab-top-left.png" ) );
+ search_tab_top_right.load( locate("data", "kicker/pics/search-tab-top-right.png" ) );
+ search_tab_top_center.load( locate("data", "kicker/pics/search-tab-top-center.png" ) );
+}
+
+void KMenu::setupUi()
+{
+ m_stacker = new TQWidgetStack( this, "m_stacker" );
+ m_stacker->setGeometry( TQRect( 90, 260, 320, 220 ) );
+ m_stacker->setSizePolicy( TQSizePolicy( (TQSizePolicy::SizeType)3, (TQSizePolicy::SizeType)3, 1, 1, m_stacker->sizePolicy().hasHeightForWidth() ) );
+ m_stacker->setPaletteBackgroundColor( TQColor( 255, 255, 255 ) );
+ // m_stacker->setFocusPolicy( TQWidget::StrongFocus );
+ m_stacker->setLineWidth( 0 );
+ m_stacker->setFocusPolicy(TQWidget::NoFocus);
+ connect(m_stacker, TQT_SIGNAL(aboutToShow(TQWidget*)), TQT_SLOT(stackWidgetRaised(TQWidget*)));
+
+ m_kcommand->setName("m_kcommand");
+}
+
+KMenu::~KMenu()
+{
+ saveConfig();
+
+ clearSubmenus();
+ delete m_filterData;
+}
+
+bool KMenu::eventFilter ( TQObject * receiver, TQEvent* e)
+{
+//kdDebug() << "eventFilter receiver=" << receiver->name() << " type=" << e->type() << endl;
+ TQWidget* raiseWidget = 0;
+ TQRect raiseRect;
+
+ if (e->type() == TQEvent::KeyPress ||
+ e->type() == TQEvent::MouseButtonPress ||
+ e->type() == TQEvent::MouseMove
+ || e->type() == TQEvent::FocusIn
+ || e->type() == TQEvent::Wheel) {
+ TQPoint p;
+
+ if (e->type() == TQEvent::MouseMove || e->type() == TQEvent::MouseButtonPress) {
+ TQMouseEvent* me = static_cast(e);
+ p = me->globalPos();
+ }
+ else if (e->type() == TQEvent::Wheel) {
+ TQWheelEvent* we = static_cast(e);
+ p = we->globalPos();
+ }
+
+ while (receiver) {
+ if (receiver == m_tabBar && (e->type()!=TQEvent::MouseMove || KickerSettings::kickoffSwitchTabsOnHover() ) ) {
+ TQTab* 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 = TQRect( 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() == TQEvent::KeyPress || e->type() == TQEvent::Wheel
+ || e->type() == TQEvent::MouseButtonPress ) ) ) &&
+ !m_isShowing) {
+ raiseWidget = m_searchWidget;
+ raiseRect = TQRect( m_searchFrame->mapToGlobal(m_searchFrame->rect().topLeft()),
+ m_searchFrame->size());
+ }
+
+ if(raiseWidget)
+ break;
+ if(receiver->isWidgetType())
+ receiver = static_cast(receiver)->parentWidget(true);
+ else
+ break;
+ }
+
+ if (e->type() == TQEvent::FocusIn && receiver && raiseWidget) {
+ m_searchResultsWidget->setFocusPolicy(TQWidget::StrongFocus);
+ m_searchActions->setFocusPolicy(raiseWidget == m_searchWidget ?
+ TQWidget::StrongFocus : TQWidget::NoFocus);
+ setTabOrder(raiseWidget, m_searchResultsWidget);
+ if (raiseWidget != m_stacker->visibleWidget()
+ && static_cast(receiver)->focusPolicy() == TQWidget::NoFocus
+ && m_stacker->id(raiseWidget) >= 0) {
+
+ m_stacker->raiseWidget(raiseWidget);
+ return true;
+ }
+
+ if (raiseWidget->focusPolicy() != TQWidget::NoFocus)
+ return false;
+ }
+
+ if (m_sloppyRegion.contains(p)) {
+ if (e->type() == TQEvent::MouseButtonPress /*&& m_sloppyTimer.isActive()*/)
+ m_sloppySourceClicked = true;
+
+ if (!m_sloppyTimer.isActive() || m_sloppySource != raiseRect) {
+ int timeout= style().styleHint(TQStyle::SH_PopupMenu_SubMenuPopupDelay);
+ if (m_sloppySourceClicked)
+ timeout = 3000;
+ m_sloppyTimer.start(timeout);
+ }
+
+ m_sloppyWidget = raiseWidget;
+ m_sloppySource = raiseRect;
+ return false;
+ }
+ }
+
+ if(e->type() == TQEvent::Enter && receiver->isWidgetType()) {
+ static_cast(receiver)->setMouseTracking(true);
+ TQToolTip::hide();
+ }
+
+ if ( ( e->type() == TQEvent::DragEnter || e->type() == TQEvent::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() == TQEvent::KeyPress && !raiseRect.isNull()) {
+ ItemView* view;
+ if (m_browserView==m_stacker->visibleWidget())
+ view = m_browserView->currentView();
+ else if (m_exitView==m_stacker->visibleWidget())
+ view = m_exitView->currentView();
+ else
+ view = dynamic_cast(m_stacker->visibleWidget());
+
+ if (view)
+ {
+ bool handled = true;
+ switch (static_cast(e)->key()) {
+ case Key_Up:
+ if (view->selectedItem()) {
+ view->setSelected(view->selectedItem()->itemAbove(),true);
+ }
+ else {
+ view->setSelected(view->lastItem(),true);
+ }
+ break;
+ case Key_Down:
+ if (view->selectedItem()) {
+ view->setSelected(view->selectedItem()->itemBelow(),true);
+ }
+ else {
+ if (view->firstChild() && view->firstChild()->isSelectable())
+ view->setSelected(view->firstChild(),true);
+ else if (view->childCount()>2)
+ view->setSelected(view->firstChild()->itemBelow(),true);
+ }
+ break;
+ case Key_Right:
+ if (view->selectedItem() && !static_cast(view->selectedItem())->hasChildren())
+ break;
+ // nobreak
+ case Key_Enter:
+ case Key_Return:
+ if (view->selectedItem())
+ view->slotItemClicked(view->selectedItem());
+
+ break;
+ case Key_Left:
+ if (m_browserView == m_stacker->visibleWidget() || m_exitView == m_stacker->visibleWidget()) {
+ FlipScrollView* flip = dynamic_cast(m_stacker->visibleWidget());
+ if (flip->showsBackButton()) {
+ if (m_browserView == m_stacker->visibleWidget())
+ goSubMenu( m_browserView->currentView()->backPath(), true );
+ else
+ view->slotItemClicked(view->firstChild());
+ }
+ break;
+ }
+ // nobreak
+ case Key_Backspace:
+ if (m_browserView == m_stacker->visibleWidget() || m_exitView == m_stacker->visibleWidget()) {
+ FlipScrollView* flip = dynamic_cast(m_stacker->visibleWidget());
+ if (flip->showsBackButton()) {
+ if (m_browserView == m_stacker->visibleWidget())
+ goSubMenu( m_browserView->currentView()->backPath(), true );
+ else
+ view->slotItemClicked(view->firstChild());
+ }
+ }
+
+ break;
+ default:
+ handled = false;
+ }
+
+ if (handled)
+ view->ensureItemVisible(view->selectedItem());
+
+ return handled;
+ }
+ }
+
+ bool r = KMenuBase::eventFilter(receiver, e);
+
+ if (!r && raiseWidget)
+ m_stacker->raiseWidget(raiseWidget);
+
+ if (e->type() == TQEvent::Wheel && raiseWidget )
+ {
+ // due to an ugly TQt bug we have to kill wheel events
+ // that cause focus switches
+ r = true;
+ }
+
+ if (e->type() == TQEvent::Enter && receiver == m_stacker)
+ {
+ TQRect r(m_stacker->mapToGlobal(TQPoint(-8,-32)), m_stacker->size());
+ r.setSize(r.size()+TQSize(16,128));
+
+ m_sloppyRegion = TQRegion(r);
+ }
+
+ // redo the sloppy region
+ if (e->type() == TQEvent::MouseMove && !r && raiseWidget)
+ {
+ TQPointArray points(4);
+
+ // hmm, eventually this should be mouse position + 10px, not
+ // just worst case. but worst case seems to work fine enough.
+ TQPoint 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+TQPoint(+raiseRect.width()/4,0));
+ points.setPoint(3, edge+TQPoint(-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+TQPoint(-raiseRect.width()/4,0));
+ points.setPoint(3, edge+TQPoint(+raiseRect.width()/4,0));
+ }
+
+ m_sloppyRegion = TQRegion(points);
+ }
+
+ return r;
+}
+
+void KMenu::slotSloppyTimeout()
+{
+ if (m_sloppyRegion.contains(TQCursor::pos()) && !m_sloppySource.isNull())
+ {
+ if ( m_sloppySource.contains(TQCursor::pos()))
+ {
+ m_stacker->raiseWidget(m_sloppyWidget);
+
+ m_sloppyWidget = 0;
+ m_sloppySource = TQRect();
+ m_sloppyRegion = TQRegion();
+ m_sloppySourceClicked = false;
+ }
+ }
+ m_sloppyTimer.stop();
+}
+
+void KMenu::paintSearchTab( bool active )
+{
+ TQPixmap canvas( m_searchFrame->size() );
+ TQPainter p( &canvas );
+
+ TQPixmap 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(TQWidget* raiseWidget)
+{
+ paintSearchTab(raiseWidget == m_searchWidget);
+
+ if (raiseWidget == m_browserView) {
+ if ( m_tabBar->currentTab() == ApplicationsTab)
+ slotGoSubMenu(TQString::null);
+ if (m_browserDirty ) {
+ createNewProgramList();
+ m_browserView->prepareRightMove();
+ m_browserView->currentView()->clear();
+ fillSubMenu(TQString::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 TQtab fixme
+#if 0
+ else if (raiseWidget == m_systemView)
+ frame = m_system;
+ else if (raiseWidget == m_favoriteView)
+ frame = m_btnFavorites;
+ if (!frame)
+ return;
+
+ if ( m_activeTab == frame )
+ return;
+
+ paintTab( m_activeTab, false );
+ paintTab( frame, true );
+
+ // if (dynamic_cast(raiseWidget))
+ // m_activeTab->setFocusProxy(static_cast(raiseWidget)->viewport());
+
+ if (0 && /*raiseWidget == m_stacker->visibleWidget() &&*/ !raiseWidget->hasFocus()) {
+
+ if (dynamic_cast