/*************************************************************************** * Copyright (C) 2006 by Aaron J. Seigo () * * Copyright (C) 2009 by Peter Penz () * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Lesser General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * * * * This library 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 * * Lesser General Public License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with this library; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * ***************************************************************************/ #include "kurlnavigatorprotocolcombo_p.h" #include #include #include #include #include #include #include #include #include namespace { const int ArrowSize = 10; } namespace KDEPrivate { KUrlNavigatorProtocolCombo::KUrlNavigatorProtocolCombo(const QString& protocol, QWidget* parent) : KUrlNavigatorButtonBase(parent), m_menu(0), m_protocols(), m_categories() { m_menu = new QMenu(this); connect(m_menu, SIGNAL(triggered(QAction*)), this, SLOT(setProtocol(QAction*))); setText(protocol); setMenu(m_menu); } void KUrlNavigatorProtocolCombo::setCustomProtocols(const QStringList& protocols) { m_protocols = protocols; m_menu->clear(); foreach (const QString& protocol, protocols) { QAction* action = m_menu->addAction(protocol); action->setData(protocol); } } QStringList KUrlNavigatorProtocolCombo::customProtocols() const { return m_protocols; } QSize KUrlNavigatorProtocolCombo::sizeHint() const { const QSize size = KUrlNavigatorButtonBase::sizeHint(); QFontMetrics fontMetrics(font()); int width = fontMetrics.width(KGlobal::locale()->removeAcceleratorMarker(text())); width += (3 * BorderWidth) + ArrowSize; return QSize(width, size.height()); } void KUrlNavigatorProtocolCombo::setProtocol(const QString& protocol) { setText(protocol); } QString KUrlNavigatorProtocolCombo::currentProtocol() const { return text(); } void KUrlNavigatorProtocolCombo::showEvent(QShowEvent* event) { KUrlNavigatorButtonBase::showEvent(event); if (!event->spontaneous() && m_protocols.isEmpty()) { m_protocols = KProtocolInfo::protocols(); qSort(m_protocols); QStringList::iterator it = m_protocols.begin(); while (it != m_protocols.end()) { const KUrl url(*it + "://"); if (!KProtocolManager::supportsListing(url)) { it = m_protocols.erase(it); } else { ++it; } } updateMenu(); } } void KUrlNavigatorProtocolCombo::paintEvent(QPaintEvent* event) { Q_UNUSED(event); QPainter painter(this); const int buttonWidth = width(); const int buttonHeight = height(); drawHoverBackground(&painter); const QColor fgColor = foregroundColor(); painter.setPen(fgColor); // draw arrow const int arrowX = buttonWidth - ArrowSize - BorderWidth; const int arrowY = (buttonHeight - ArrowSize) / 2; QStyleOption option; option.rect = QRect(arrowX, arrowY, ArrowSize, ArrowSize); option.palette = palette(); option.palette.setColor(QPalette::Text, fgColor); option.palette.setColor(QPalette::WindowText, fgColor); option.palette.setColor(QPalette::ButtonText, fgColor); style()->drawPrimitive(QStyle::PE_IndicatorArrowDown, &option, &painter, this ); // draw text const int textWidth = arrowX - (2 * BorderWidth); int alignment = Qt::AlignCenter | Qt::TextShowMnemonic; if (!style()->styleHint(QStyle::SH_UnderlineShortcut, &option, this)) { alignment |= Qt::TextHideMnemonic; } style()->drawItemText(&painter, QRect(BorderWidth, 0, textWidth, buttonHeight), alignment, option.palette, isEnabled(), text()); } void KUrlNavigatorProtocolCombo::setProtocol(QAction* action) { const QString protocol = action->data().toString(); setText(protocol); emit activated(protocol); } void KUrlNavigatorProtocolCombo::updateMenu() { initializeCategories(); qSort(m_protocols); // move all protocols into the corresponding category of 'items' QList items[CategoryCount]; foreach (const QString& protocol, m_protocols) { if (m_categories.contains(protocol)) { const ProtocolCategory category = m_categories.value(protocol); items[category].append(protocol); } else { items[OtherCategory].append(protocol); } } // Create the menu that includes all entries from 'items'. The categories // CoreCategory and PlacesCategory are placed at the top level, the remaining // categories are placed in sub menus. QMenu* menu = m_menu; for (int category = 0; category < CategoryCount; ++category) { if (items[category].count() > 0) { switch (category) { case DevicesCategory: menu = m_menu->addMenu(i18nc("@item:inmenu", "Devices")); break; case OtherCategory: menu = m_menu->addMenu(i18nc("@item:inmenu", "Other")); break; case CoreCategory: case PlacesCategory: default: break; } foreach (const QString& protocol, items[category]) { QAction* action = menu->addAction(protocol); action->setData(protocol); } if (menu == m_menu) { menu->addSeparator(); } } } } void KUrlNavigatorProtocolCombo::initializeCategories() { if (m_categories.isEmpty()) { m_categories.insert("file", CoreCategory); m_categories.insert("ftp", CoreCategory); m_categories.insert("sftp", CoreCategory); m_categories.insert("trash", PlacesCategory); m_categories.insert("remote", PlacesCategory); m_categories.insert("camera", DevicesCategory); m_categories.insert("mtp", DevicesCategory); m_categories.insert("network", OtherCategory); } } } // namespace KDEPrivate #include "moc_kurlnavigatorprotocolcombo_p.cpp"