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