1 | /*************************************************************************** |
2 | * Copyright (C) 2006 by Aaron J. Seigo (<aseigo@kde.org>) * |
3 | * Copyright (C) 2009 by Peter Penz (<peter.penz@kde.org>) * |
4 | * * |
5 | * This library is free software; you can redistribute it and/or * |
6 | * modify it under the terms of the GNU Lesser General Public * |
7 | * License as published by the Free Software Foundation; either * |
8 | * version 2 of the License, or (at your option) any later version. * |
9 | * * |
10 | * This library is distributed in the hope that it will be useful, * |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * |
13 | * Lesser General Public License for more details. * |
14 | * * |
15 | * You should have received a copy of the GNU Lesser General Public * |
16 | * License along with this library; if not, write to the * |
17 | * Free Software Foundation, Inc., * |
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * |
19 | ***************************************************************************/ |
20 | |
21 | #include "kurlnavigatorprotocolcombo_p.h" |
22 | |
23 | #include <QtGui/QAction> |
24 | #include <QtGui/QMenu> |
25 | #include <QtGui/QPainter> |
26 | #include <QtGui/QPaintEvent> |
27 | #include <QtGui/QStyleOption> |
28 | |
29 | #include <klocale.h> |
30 | #include <kprotocolinfo.h> |
31 | #include <kprotocolmanager.h> |
32 | #include <kurlnavigator.h> |
33 | |
34 | namespace |
35 | { |
36 | const int ArrowSize = 10; |
37 | } |
38 | |
39 | namespace KDEPrivate |
40 | { |
41 | |
42 | KUrlNavigatorProtocolCombo::KUrlNavigatorProtocolCombo(const QString& protocol, QWidget* parent) : |
43 | KUrlNavigatorButtonBase(parent), |
44 | m_menu(0), |
45 | m_protocols(), |
46 | m_categories() |
47 | { |
48 | m_menu = new QMenu(this); |
49 | connect(m_menu, SIGNAL(triggered(QAction*)), this, SLOT(setProtocol(QAction*))); |
50 | setText(protocol); |
51 | setMenu(m_menu); |
52 | } |
53 | |
54 | void KUrlNavigatorProtocolCombo::setCustomProtocols(const QStringList& protocols) |
55 | { |
56 | m_protocols = protocols; |
57 | m_menu->clear(); |
58 | |
59 | foreach (const QString& protocol, protocols) { |
60 | QAction* action = m_menu->addAction(protocol); |
61 | action->setData(protocol); |
62 | } |
63 | } |
64 | |
65 | QSize KUrlNavigatorProtocolCombo::sizeHint() const |
66 | { |
67 | const QSize size = KUrlNavigatorButtonBase::sizeHint(); |
68 | |
69 | QFontMetrics fontMetrics(font()); |
70 | int width = fontMetrics.width(KGlobal::locale()->removeAcceleratorMarker(text())); |
71 | width += (3 * BorderWidth) + ArrowSize; |
72 | |
73 | return QSize(width, size.height()); |
74 | } |
75 | |
76 | void KUrlNavigatorProtocolCombo::setProtocol(const QString& protocol) |
77 | { |
78 | setText(protocol); |
79 | } |
80 | |
81 | QString KUrlNavigatorProtocolCombo::currentProtocol() const |
82 | { |
83 | return text(); |
84 | } |
85 | |
86 | void KUrlNavigatorProtocolCombo::showEvent(QShowEvent* event) |
87 | { |
88 | KUrlNavigatorButtonBase::showEvent(event); |
89 | if (!event->spontaneous() && m_protocols.isEmpty()) { |
90 | m_protocols = KProtocolInfo::protocols(); |
91 | qSort(m_protocols); |
92 | |
93 | QStringList::iterator it = m_protocols.begin(); |
94 | while (it != m_protocols.end()) { |
95 | const KUrl url(*it + "://" ); |
96 | if (!KProtocolManager::supportsListing(url)) { |
97 | it = m_protocols.erase(it); |
98 | } else { |
99 | ++it; |
100 | } |
101 | } |
102 | |
103 | updateMenu(); |
104 | } |
105 | } |
106 | |
107 | void KUrlNavigatorProtocolCombo::paintEvent(QPaintEvent* event) |
108 | { |
109 | Q_UNUSED(event); |
110 | |
111 | QPainter painter(this); |
112 | const int buttonWidth = width(); |
113 | const int buttonHeight = height(); |
114 | |
115 | drawHoverBackground(&painter); |
116 | |
117 | const QColor fgColor = foregroundColor(); |
118 | painter.setPen(fgColor); |
119 | |
120 | // draw arrow |
121 | const int arrowX = buttonWidth - ArrowSize - BorderWidth; |
122 | const int arrowY = (buttonHeight - ArrowSize) / 2; |
123 | |
124 | QStyleOption option; |
125 | option.rect = QRect(arrowX, arrowY, ArrowSize, ArrowSize); |
126 | option.palette = palette(); |
127 | option.palette.setColor(QPalette::Text, fgColor); |
128 | option.palette.setColor(QPalette::WindowText, fgColor); |
129 | option.palette.setColor(QPalette::ButtonText, fgColor); |
130 | style()->drawPrimitive(QStyle::PE_IndicatorArrowDown, &option, &painter, this ); |
131 | |
132 | // draw text |
133 | const int textWidth = arrowX - (2 * BorderWidth); |
134 | int alignment = Qt::AlignCenter | Qt::TextShowMnemonic; |
135 | if (!style()->styleHint(QStyle::SH_UnderlineShortcut, &option, this)) { |
136 | alignment |= Qt::TextHideMnemonic; |
137 | } |
138 | style()->drawItemText(&painter, QRect(BorderWidth, 0, textWidth, buttonHeight), |
139 | alignment, option.palette, isEnabled(), text()); |
140 | } |
141 | |
142 | void KUrlNavigatorProtocolCombo::setProtocol(QAction* action) |
143 | { |
144 | const QString protocol = action->data().toString(); |
145 | setText(protocol); |
146 | emit activated(protocol); |
147 | } |
148 | |
149 | void KUrlNavigatorProtocolCombo::() |
150 | { |
151 | initializeCategories(); |
152 | qSort(m_protocols); |
153 | |
154 | // move all protocols into the corresponding category of 'items' |
155 | QList<QString> items[CategoryCount]; |
156 | foreach (const QString& protocol, m_protocols) { |
157 | if (m_categories.contains(protocol)) { |
158 | const ProtocolCategory category = m_categories.value(protocol); |
159 | items[category].append(protocol); |
160 | } else { |
161 | items[OtherCategory].append(protocol); |
162 | } |
163 | } |
164 | |
165 | // Create the menu that includes all entries from 'items'. The categories |
166 | // CoreCategory and PlacesCategory are placed at the top level, the remaining |
167 | // categories are placed in sub menus. |
168 | QMenu* = m_menu; |
169 | for (int category = 0; category < CategoryCount; ++category) { |
170 | if (items[category].count() > 0) { |
171 | switch (category) { |
172 | case DevicesCategory: |
173 | menu = m_menu->addMenu(i18nc("@item:inmenu" , "Devices" )); |
174 | break; |
175 | |
176 | case SubversionCategory: |
177 | menu = m_menu->addMenu(i18nc("@item:inmenu" , "Subversion" )); |
178 | break; |
179 | |
180 | case OtherCategory: |
181 | menu = m_menu->addMenu(i18nc("@item:inmenu" , "Other" )); |
182 | break; |
183 | |
184 | case CoreCategory: |
185 | case PlacesCategory: |
186 | default: |
187 | break; |
188 | } |
189 | |
190 | foreach (const QString& protocol, items[category]) { |
191 | QAction* action = menu->addAction(protocol); |
192 | action->setData(protocol); |
193 | } |
194 | |
195 | if (menu == m_menu) { |
196 | menu->addSeparator(); |
197 | } |
198 | } |
199 | } |
200 | } |
201 | |
202 | void KUrlNavigatorProtocolCombo::initializeCategories() |
203 | { |
204 | if (m_categories.isEmpty()) { |
205 | m_categories.insert("file" , CoreCategory); |
206 | m_categories.insert("ftp" , CoreCategory); |
207 | m_categories.insert("fish" , CoreCategory); |
208 | m_categories.insert("nfs" , CoreCategory); |
209 | m_categories.insert("sftp" , CoreCategory); |
210 | m_categories.insert("smb" , CoreCategory); |
211 | m_categories.insert("webdav" , CoreCategory); |
212 | |
213 | m_categories.insert("desktop" , PlacesCategory); |
214 | m_categories.insert("fonts" , PlacesCategory); |
215 | m_categories.insert("programs" , PlacesCategory); |
216 | m_categories.insert("settings" , PlacesCategory); |
217 | m_categories.insert("trash" , PlacesCategory); |
218 | |
219 | m_categories.insert("floppy" , DevicesCategory); |
220 | m_categories.insert("camera" , DevicesCategory); |
221 | m_categories.insert("remote" , DevicesCategory); |
222 | |
223 | m_categories.insert("svn" , SubversionCategory); |
224 | m_categories.insert("svn+file" , SubversionCategory); |
225 | m_categories.insert("svn+http" , SubversionCategory); |
226 | m_categories.insert("svn+https" , SubversionCategory); |
227 | m_categories.insert("svn+ssh" , SubversionCategory); |
228 | } |
229 | } |
230 | |
231 | } // namespace KDEPrivate |
232 | |
233 | #include "kurlnavigatorprotocolcombo_p.moc" |
234 | |