00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "kprotocolcombo_p.h"
00022
00023 #include <QtGui/QAction>
00024 #include <QtGui/QMenu>
00025 #include <QtGui/QPainter>
00026 #include <QtGui/QPaintEvent>
00027 #include <QtGui/QStyleOption>
00028
00029 #include <klocale.h>
00030 #include <kprotocolinfo.h>
00031 #include <kprotocolmanager.h>
00032 #include <kurlnavigator.h>
00033
00034 const int ARROW_SIZE = 10;
00035
00036 KProtocolCombo::KProtocolCombo(const QString& protocol, KUrlNavigator* parent) :
00037 KUrlButton(parent),
00038 m_menu(0),
00039 m_protocols(),
00040 m_categories()
00041 {
00042 m_menu = new QMenu(this);
00043 connect(m_menu, SIGNAL(triggered(QAction*)), this, SLOT(setProtocol(QAction*)));
00044 setText(protocol);
00045 setMenu(m_menu);
00046 }
00047
00048 void KProtocolCombo::setCustomProtocols(const QStringList& protocols)
00049 {
00050 m_protocols = protocols;
00051 m_menu->clear();
00052
00053 foreach (const QString& protocol, protocols) {
00054 QAction* action = m_menu->addAction(protocol);
00055 action->setData(protocol);
00056 }
00057 }
00058
00059 QSize KProtocolCombo::sizeHint() const
00060 {
00061 QSize size = KUrlButton::sizeHint();
00062
00063 QFontMetrics fontMetrics(font());
00064 int width = fontMetrics.width(text());
00065 width += (3 * BorderWidth) + ARROW_SIZE;
00066
00067 return QSize(width, size.height());
00068 }
00069
00070 void KProtocolCombo::setProtocol(const QString& protocol)
00071 {
00072 setText(protocol);
00073 }
00074
00075 QString KProtocolCombo::currentProtocol() const
00076 {
00077 return text();
00078 }
00079
00080 void KProtocolCombo::showEvent(QShowEvent* event)
00081 {
00082 KUrlButton::showEvent(event);
00083 if (!event->spontaneous() && m_protocols.isEmpty()) {
00084 m_protocols = KProtocolInfo::protocols();
00085 qSort(m_protocols);
00086
00087 QStringList::iterator it = m_protocols.begin();
00088 while (it != m_protocols.end()) {
00089 const KUrl url(*it + "://");
00090 if (!KProtocolManager::supportsListing(url)) {
00091 it = m_protocols.erase(it);
00092 } else {
00093 ++it;
00094 }
00095 }
00096
00097 updateMenu();
00098 }
00099 }
00100
00101 void KProtocolCombo::paintEvent(QPaintEvent* event)
00102 {
00103 Q_UNUSED(event);
00104
00105 QPainter painter(this);
00106 const int buttonWidth = width();
00107 const int buttonHeight = height();
00108
00109 drawHoverBackground(&painter);
00110
00111 const QColor fgColor = foregroundColor();
00112 painter.setPen(fgColor);
00113
00114
00115 const int arrowX = buttonWidth - ARROW_SIZE - BorderWidth;
00116 const int arrowY = (buttonHeight - ARROW_SIZE) / 2;
00117
00118 QStyleOption option;
00119 option.rect = QRect(arrowX, arrowY, ARROW_SIZE, ARROW_SIZE);
00120 option.palette = palette();
00121 option.palette.setColor(QPalette::Text, fgColor);
00122 option.palette.setColor(QPalette::WindowText, fgColor);
00123 option.palette.setColor(QPalette::ButtonText, fgColor);
00124 style()->drawPrimitive(QStyle::PE_IndicatorArrowDown, &option, &painter, this );
00125
00126
00127 const int textWidth = arrowX - (2 * BorderWidth);
00128 painter.drawText(QRect(BorderWidth, 0, textWidth, buttonHeight), Qt::AlignCenter, text());
00129 }
00130
00131 void KProtocolCombo::setProtocol(QAction* action)
00132 {
00133 const QString protocol = action->data().toString();
00134 setText(protocol);
00135 emit activated(protocol);
00136 }
00137
00138 void KProtocolCombo::updateMenu()
00139 {
00140 initializeCategories();
00141 qSort(m_protocols);
00142
00143
00144 QList<QString> items[CategoryCount];
00145 foreach (const QString& protocol, m_protocols) {
00146 if (m_categories.contains(protocol)) {
00147 const ProtocolCategory category = m_categories.value(protocol);
00148 items[category].append(protocol);
00149 } else {
00150 items[OtherCategory].append(protocol);
00151 }
00152 }
00153
00154
00155
00156
00157 QMenu* menu = m_menu;
00158 for (int category = 0; category < CategoryCount; ++category) {
00159 if (items[category].count() > 0) {
00160 switch (category) {
00161 case DevicesCategory:
00162 menu = m_menu->addMenu(i18nc("@item:inmenu", "Devices"));
00163 break;
00164
00165 case SubversionCategory:
00166 menu = m_menu->addMenu(i18nc("@item:inmenu", "Subversion"));
00167 break;
00168
00169 case OtherCategory:
00170 menu = m_menu->addMenu(i18nc("@item:inmenu", "Other"));
00171 break;
00172
00173 case CoreCategory:
00174 case PlacesCategory:
00175 default:
00176 break;
00177 }
00178
00179 foreach (const QString& protocol, items[category]) {
00180 QAction* action = menu->addAction(protocol);
00181 action->setData(protocol);
00182 }
00183
00184 if (menu == m_menu) {
00185 menu->addSeparator();
00186 }
00187 }
00188 }
00189 }
00190
00191 void KProtocolCombo::initializeCategories()
00192 {
00193 if (m_categories.isEmpty()) {
00194 m_categories.insert("file", CoreCategory);
00195 m_categories.insert("ftp", CoreCategory);
00196 m_categories.insert("fish", CoreCategory);
00197 m_categories.insert("nfs", CoreCategory);
00198 m_categories.insert("sftp", CoreCategory);
00199 m_categories.insert("smb", CoreCategory);
00200 m_categories.insert("webdav", CoreCategory);
00201
00202 m_categories.insert("desktop", PlacesCategory);
00203 m_categories.insert("fonts", PlacesCategory);
00204 m_categories.insert("programs", PlacesCategory);
00205 m_categories.insert("settings", PlacesCategory);
00206 m_categories.insert("trash", PlacesCategory);
00207
00208 m_categories.insert("floppy", DevicesCategory);
00209 m_categories.insert("camera", DevicesCategory);
00210 m_categories.insert("remote", DevicesCategory);
00211
00212 m_categories.insert("svn", SubversionCategory);
00213 m_categories.insert("svn+file", SubversionCategory);
00214 m_categories.insert("svn+http", SubversionCategory);
00215 m_categories.insert("svn+https", SubversionCategory);
00216 m_categories.insert("svn+ssh", SubversionCategory);
00217 }
00218 }
00219
00220 #include "kprotocolcombo_p.moc"