summaryrefslogtreecommitdiffstats
path: root/kicker/kicker/ui/addapplet.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kicker/kicker/ui/addapplet.cpp')
-rw-r--r--kicker/kicker/ui/addapplet.cpp542
1 files changed, 542 insertions, 0 deletions
diff --git a/kicker/kicker/ui/addapplet.cpp b/kicker/kicker/ui/addapplet.cpp
new file mode 100644
index 000000000..e7ac47c9c
--- /dev/null
+++ b/kicker/kicker/ui/addapplet.cpp
@@ -0,0 +1,542 @@
+/*****************************************************************
+
+Copyright (c) 2005 Marc Cramdal
+Copyright (c) 2005 Aaron Seigo <aseigo@kde.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+******************************************************************/
+
+#include <qapplication.h>
+#include <qcombobox.h>
+#include <qdir.h>
+#include <qframe.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qlineedit.h>
+#include <qpalette.h>
+#include <qscrollview.h>
+#include <qtimer.h>
+#include <qsizepolicy.h>
+
+#include <kiconloader.h>
+#include <kdebug.h>
+#include <kglobalsettings.h>
+#include <kpushbutton.h>
+#include <kstandarddirs.h>
+#include <kstdguiitem.h>
+
+#include <paneldrag.h>
+
+#include "addapplet.h"
+#include "addappletvisualfeedback.h"
+#include "appletwidget.h"
+#include "appletview.h"
+#include "container_applet.h"
+#include "container_extension.h"
+#include "containerarea.h"
+#include "kicker.h"
+#include "kickerSettings.h"
+#include "menuinfo.h"
+#include "pluginmanager.h"
+
+AppletWidget::AppletWidget(const AppletInfo& info, bool odd, QWidget *parent)
+ : AppletItem(parent),
+ m_appletInfo(info),
+ m_odd(odd),
+ m_selected(false)
+{
+ setFocusPolicy(QWidget::StrongFocus);
+ setSelected(m_selected);
+
+ itemTitle->setText("<h3>" + info.name() + "</h3>");
+ itemTitle->installEventFilter(this);
+
+ if (info.comment() != info.name())
+ {
+ itemDescription->setText(info.comment());
+ }
+
+ itemDescription->installEventFilter(this);
+
+ KIconLoader * ldr = KGlobal::iconLoader();
+ QPixmap icon = ldr->loadIcon(info.icon(), KIcon::Panel, KIcon::SizeLarge);
+ itemPixmap->setPixmap(icon);
+ itemPixmap->installEventFilter(this);
+}
+
+bool AppletWidget::eventFilter(QObject*, QEvent* e)
+{
+ if (e->type() == QEvent::MouseButtonPress)
+ {
+ QMouseEvent* me = static_cast<QMouseEvent*>(e);
+ if (me->button() & LeftButton)
+ {
+ m_dragStart = me->pos();
+ }
+ }
+ else if (m_dragStart.isNull())
+ {
+ return false;
+ }
+
+ if (e->type() == QEvent::MouseMove)
+ {
+ QMouseEvent* me = static_cast<QMouseEvent*>(e);
+ if ((me->pos() - m_dragStart).manhattanLength() >
+ KGlobalSettings::dndEventDelay())
+ {
+ AppletInfoDrag* drag = new AppletInfoDrag(m_appletInfo, this);
+
+ if (itemPixmap->pixmap())
+ {
+ drag->setPixmap(*itemPixmap->pixmap());
+ }
+
+ drag->dragCopy();
+
+ return true;
+ }
+ }
+ else if (e->type() == QEvent::MouseButtonRelease)
+ {
+ m_dragStart = QPoint();
+ }
+
+ return false;
+}
+
+void AppletWidget::keyPressEvent(QKeyEvent *e)
+{
+ if (e->key() == Qt::Key_Enter ||
+ e->key() == Qt::Key_Return)
+ {
+ emit doubleClicked(this);
+ }
+ else if (e->key() == Qt::Key_Up)
+ {
+ QKeyEvent fakedKeyPress(QEvent::KeyPress, Qt::Key_BackTab, 0, 0);
+ QKeyEvent fakedKeyRelease(QEvent::KeyRelease, Key_BackTab, 0, 0);
+ QApplication::sendEvent(this, &fakedKeyPress);
+ QApplication::sendEvent(this, &fakedKeyRelease);
+ }
+ else if (e->key() == Qt::Key_Down)
+ {
+ QKeyEvent fakedKeyPress(QEvent::KeyPress, Qt::Key_Tab, 0, 0);
+ QKeyEvent fakedKeyRelease(QEvent::KeyRelease, Key_Escape, 0, 0);
+ QApplication::sendEvent(this, &fakedKeyPress);
+ QApplication::sendEvent(this, &fakedKeyRelease);
+ }
+ else
+ {
+ AppletItem::keyPressEvent(e);
+ }
+}
+
+void AppletWidget::mousePressEvent(QMouseEvent *e)
+{
+ if (e->button() == QMouseEvent::LeftButton)
+ {
+ emit clicked(this);
+ m_dragStart = e->pos();
+ }
+
+ setFocus();
+ QWidget::mousePressEvent(e);
+}
+
+void AppletWidget::mouseMoveEvent(QMouseEvent *e)
+{
+ if (e->button() == QMouseEvent::LeftButton &&
+ !m_dragStart.isNull() &&
+ (e->pos() - m_dragStart).manhattanLength() >
+ KGlobalSettings::dndEventDelay())
+ {
+ AppletInfoDrag* drag = new AppletInfoDrag(m_appletInfo, this);
+
+ if (itemPixmap->pixmap())
+ {
+ drag->setPixmap(*itemPixmap->pixmap());
+ }
+
+ drag->dragCopy();
+ }
+}
+
+void AppletWidget::mouseReleaseEvent(QMouseEvent *e)
+{
+ m_dragStart = QPoint();
+ QWidget::mouseReleaseEvent(e);
+}
+
+void AppletWidget::mouseDoubleClickEvent(QMouseEvent *e)
+{
+ if (!e->button() == QMouseEvent::LeftButton)
+ {
+ AppletItem::mouseDoubleClickEvent(e);
+ return;
+ }
+
+ emit doubleClicked(this);
+}
+
+void AppletWidget::setSelected(bool selected)
+{
+ m_selected = selected;
+
+ // for now just used to switch colours around =)
+ if (m_selected)
+ {
+ setPaletteBackgroundColor(KGlobalSettings::highlightColor());
+ setPaletteForegroundColor(KGlobalSettings::highlightedTextColor());
+ }
+ else if (m_odd)
+ {
+ setPaletteBackgroundColor(KGlobalSettings::baseColor());
+ setPaletteForegroundColor(KGlobalSettings::textColor());
+ }
+ else
+ {
+ setPaletteBackgroundColor(KGlobalSettings::alternateBackgroundColor());
+ setPaletteForegroundColor(KGlobalSettings::textColor());
+ }
+}
+
+void AppletWidget::setOdd(bool odd)
+{
+ m_odd = odd;
+ setSelected(m_selected);
+}
+
+void AppletWidget::focusInEvent(QFocusEvent*)
+{
+ emit clicked(this);
+}
+
+AddAppletDialog::AddAppletDialog(ContainerArea* cArea,
+ QWidget* parent,
+ const char* name)
+ : KDialogBase(parent, name, false, i18n("Add Applet"), 0),
+ m_selectedApplet(0),
+ m_containerArea(cArea),
+ m_insertionPoint(Kicker::the()->insertionPoint()),
+ m_closing(false),
+ m_searchDelay(new QTimer(this))
+{
+ m_mainWidget = new AppletView(this, "AddAppletDialog::m_mainWidget");
+ m_mainWidget->appletScrollView->setResizePolicy(QScrollView::Manual);
+ m_mainWidget->appletScrollView->setHScrollBarMode(QScrollView::AlwaysOff);
+ m_mainWidget->appletScrollView->viewport()->setPaletteBackgroundColor(KGlobalSettings::baseColor());
+
+ setMainWidget(m_mainWidget);
+
+ resize(configDialogSize("AddAppletDialog Settings"));
+ centerOnScreen(this);
+
+ KGuiItem addGuiItem = KStdGuiItem::add();
+ addGuiItem.setText(m_mainWidget->appletInstall->text());
+ m_mainWidget->appletInstall->setEnabled(false);
+ m_mainWidget->appletInstall->setGuiItem(addGuiItem);
+ m_mainWidget->closeButton->setGuiItem(KStdGuiItem::close());
+
+ connect(m_mainWidget->appletSearch, SIGNAL(textChanged(const QString&)), this, SLOT(delayedSearch()));
+ connect(m_searchDelay, SIGNAL(timeout()), this, SLOT(search()));
+ connect(m_mainWidget->appletFilter, SIGNAL(activated(int)), this, SLOT(filter(int)));
+ connect(m_mainWidget->appletInstall, SIGNAL(clicked()), this, SLOT(addCurrentApplet()));
+ connect(m_mainWidget->closeButton, SIGNAL(clicked()), this, SLOT(close()));
+
+ m_selectedType = AppletInfo::Undefined;
+ m_appletBox = 0;
+
+ QTimer::singleShot(0, this, SLOT(populateApplets()));
+}
+
+void AddAppletDialog::updateInsertionPoint()
+{
+ m_insertionPoint = Kicker::the()->insertionPoint();
+}
+
+
+void AddAppletDialog::closeEvent(QCloseEvent* e)
+{
+ m_closing = true;
+ saveDialogSize("AddAppletDialog Settings");
+ KDialogBase::closeEvent(e);
+}
+
+void AddAppletDialog::resizeAppletView()
+{
+ int w, h;
+ QScrollView *v = m_mainWidget->appletScrollView;
+
+ if (m_closing)
+ return;
+
+ for (int i = 0; i < 3; i++)
+ {
+ m_appletBox->layout()->activate();
+ w = v->visibleWidth();
+ h = m_appletBox->layout()->minimumSize().height();
+ v->resizeContents(w, QMAX(h, v->visibleHeight()));
+ if (w == m_appletBox->width() && h == m_appletBox->height())
+ break;
+ m_appletBox->resize(w, h);
+ v->updateScrollBars();
+ }
+}
+
+bool AddAppletDialog::eventFilter(QObject *o, QEvent *e)
+{
+ if (e->type() == QEvent::Resize)
+ QTimer::singleShot(0, this, SLOT(resizeAppletView()));
+
+ return QObject::eventFilter(o, e);
+}
+
+void AddAppletDialog::populateApplets()
+{
+ m_appletBox = new QWidget(m_mainWidget->appletScrollView->viewport());
+ m_appletBox->setPaletteBackgroundColor(KGlobalSettings::baseColor());
+ m_mainWidget->appletScrollView->addChild(m_appletBox, 0, 0);
+ m_appletBox->show();
+ QVBoxLayout* layout = new QVBoxLayout(m_appletBox);
+ layout->setMargin(0);
+
+ m_mainWidget->appletScrollView->installEventFilter(this);
+
+ /* Three steps
+ * - First we load the applets
+ * - We load the special buttons
+ * - Then we begin to populate the scrollview with the AppletWidget(s)
+ */
+ AppletInfo::List appletInfoList;
+
+ // Loading applets
+ appletInfoList = PluginManager::applets(false, &appletInfoList);
+
+ // Loading built in buttons
+ appletInfoList = PluginManager::builtinButtons(false, &appletInfoList);
+
+ // Loading special buttons
+ appletInfoList = PluginManager::specialButtons(false, &appletInfoList);
+
+ qHeapSort(appletInfoList);
+
+ int i = 0;
+ bool odd = true;
+ QWidget* prevTabWidget = m_mainWidget->appletFilter;
+
+ for (AppletInfo::List::iterator it = appletInfoList.begin();
+ !m_closing && it != appletInfoList.end();
+ ++i)
+ {
+ if ((*it).isHidden() || (*it).name().isEmpty() ||
+ ((*it).isUniqueApplet() &&
+ PluginManager::the()->hasInstance(*it)))
+ {
+ it = appletInfoList.erase(it);
+ --i;
+ continue;
+ }
+
+ AppletWidget *itemWidget = new AppletWidget(*it, odd, m_appletBox);
+
+ if (m_mainWidget->appletSearch->text().isEmpty() ||
+ appletMatchesSearch(itemWidget, m_mainWidget->appletSearch->text()))
+ {
+ itemWidget->show();
+ odd = !odd;
+ }
+ else
+ {
+ itemWidget->hide();
+ }
+
+ layout->insertWidget(i, itemWidget);
+ m_appletWidgetList.append(itemWidget);
+ setTabOrder(prevTabWidget, itemWidget);
+ prevTabWidget = itemWidget;
+
+ connect(itemWidget, SIGNAL(clicked(AppletWidget*)),
+ this, SLOT(selectApplet(AppletWidget*)));
+ connect(itemWidget, SIGNAL(doubleClicked(AppletWidget*)),
+ this, SLOT(addApplet(AppletWidget*)));
+
+ if (m_closing)
+ {
+ return;
+ }
+
+ ++it;
+ }
+
+ resizeAppletView();
+
+ m_mainWidget->closeButton->setEnabled(true);
+}
+
+void AddAppletDialog::selectApplet(AppletWidget *applet)
+{
+ m_mainWidget->appletInstall->setEnabled(true);
+
+ if (m_selectedApplet)
+ {
+ m_selectedApplet->setSelected(false);
+ }
+
+ m_selectedApplet = applet;
+
+ if (m_selectedApplet)
+ {
+ m_selectedApplet->setSelected(true);
+ }
+}
+
+void AddAppletDialog::addCurrentApplet()
+{
+ addApplet(m_selectedApplet);
+}
+
+void AddAppletDialog::addApplet(AppletWidget* applet)
+{
+ if (!applet)
+ {
+ return;
+ }
+
+ QPoint prevInsertionPoint = Kicker::the()->insertionPoint();
+ Kicker::the()->setInsertionPoint(m_insertionPoint);
+
+ const QWidget* appletContainer = 0;
+
+ if (applet->info().type() == AppletInfo::Applet)
+ {
+ appletContainer = m_containerArea->addApplet(applet->info());
+
+ if (applet->info().isUniqueApplet() &&
+ PluginManager::the()->hasInstance(applet->info()))
+ {
+ applet->hide();
+
+ // reset the odd/even colouring from this item on down in the list
+ bool odd = applet->odd();
+ AppletWidget::List::const_iterator it = m_appletWidgetList.find(applet);
+ for (; it != m_appletWidgetList.constEnd(); ++it)
+ {
+ if ((*it)->isHidden())
+ {
+ continue;
+ }
+
+ (*it)->setOdd(odd);
+ odd = !odd;
+ }
+ }
+ }
+ else if (applet->info().type() & AppletInfo::Button)
+ {
+ appletContainer = m_containerArea->addButton(applet->info());
+ }
+
+ if (appletContainer)
+ {
+ ExtensionContainer* ec =
+ dynamic_cast<ExtensionContainer*>(m_containerArea->topLevelWidget());
+
+ if (ec)
+ {
+ // unhide the panel and keep it unhidden for at least the time the
+ // helper tip will be there
+ ec->unhideIfHidden(KickerSettings::mouseOversSpeed() + 2500);
+ }
+
+ new AddAppletVisualFeedback(applet, appletContainer,
+ m_containerArea->popupDirection());
+ }
+
+ Kicker::the()->setInsertionPoint(prevInsertionPoint);
+}
+
+bool AddAppletDialog::appletMatchesSearch(const AppletWidget* w,
+ const QString& s)
+{
+ if (w->info().type() == AppletInfo::Applet &&
+ w->info().isUniqueApplet() &&
+ PluginManager::the()->hasInstance(w->info()))
+ {
+ return false;
+ }
+
+ return (m_selectedType == AppletInfo::Undefined ||
+ w->info().type() & m_selectedType) &&
+ (w->info().name().contains(s, false) ||
+ w->info().comment().contains(s, false));
+}
+
+void AddAppletDialog::delayedSearch()
+{
+ if (!m_searchDelay->isActive())
+ {
+ m_searchDelay->start(300, true);
+ }
+}
+
+void AddAppletDialog::search()
+{
+ QString s = m_mainWidget->appletSearch->text();
+ bool odd = true;
+ AppletWidget::List::const_iterator it = m_appletWidgetList.constBegin();
+ AppletWidget::List::const_iterator itEnd = m_appletWidgetList.constEnd();
+
+ for (; it != itEnd; ++it)
+ {
+ AppletWidget* w = *it;
+ if (appletMatchesSearch(w, s))
+ {
+ w->setOdd(odd);
+ w->show();
+ odd = !odd;
+ }
+ else
+ {
+ w->hide();
+ }
+ }
+
+ QTimer::singleShot(0, this, SLOT(resizeAppletView()));
+}
+
+void AddAppletDialog::filter(int i)
+{
+ m_selectedType = AppletInfo::Undefined;
+
+ if (i == 1)
+ {
+ m_selectedType = AppletInfo::Applet;
+ }
+ else if (i == 2)
+ {
+ m_selectedType = AppletInfo::Button;
+ }
+
+ search();
+}
+
+#include "addapplet.moc"
+#include "appletwidget.moc"
+