Changeset View
Standalone View
src/ViewContainer.cpp
Show All 15 Lines | 1 | /* | |||
---|---|---|---|---|---|
16 | You should have received a copy of the GNU General Public License | 16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | 17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | 18 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
19 | 02110-1301 USA. | 19 | 02110-1301 USA. | ||
20 | */ | 20 | */ | ||
21 | 21 | | |||
22 | // Own | 22 | // Own | ||
23 | #include "ViewContainer.h" | 23 | #include "ViewContainer.h" | ||
24 | | ||||
25 | #include <config-konsole.h> | 24 | #include <config-konsole.h> | ||
26 | 25 | | |||
27 | // Qt | 26 | // Qt | ||
28 | #include <QStackedWidget> | 27 | #include <QTabBar> | ||
29 | #include <QToolButton> | 28 | #include <QMenu> | ||
30 | #include <QDrag> | | |||
31 | #include <QDragMoveEvent> | | |||
32 | #include <QMimeData> | | |||
33 | #include <QHBoxLayout> | | |||
34 | #include <QVBoxLayout> | | |||
35 | 29 | | |||
36 | // KDE | 30 | // KDE | ||
37 | #include <KColorScheme> | 31 | #include <KColorScheme> | ||
38 | #include <KColorUtils> | 32 | #include <KColorUtils> | ||
39 | #include <KLocalizedString> | 33 | #include <KLocalizedString> | ||
40 | #include <KActionCollection> | 34 | #include <KActionCollection> | ||
41 | #include <QMenu> | | |||
42 | 35 | | |||
43 | // Konsole | 36 | // Konsole | ||
44 | #include "IncrementalSearchBar.h" | 37 | #include "IncrementalSearchBar.h" | ||
45 | #include "ViewProperties.h" | 38 | #include "ViewProperties.h" | ||
46 | #include "ViewContainerTabBar.h" | | |||
47 | #include "ProfileList.h" | 39 | #include "ProfileList.h" | ||
48 | #include "ViewManager.h" | 40 | #include "ViewManager.h" | ||
49 | #include "KonsoleSettings.h" | 41 | #include "KonsoleSettings.h" | ||
50 | #include "SessionController.h" | 42 | #include "SessionController.h" | ||
51 | 43 | | |||
52 | // TODO Perhaps move everything which is Konsole-specific into different files | 44 | // TODO Perhaps move everything which is Konsole-specific into different files | ||
53 | 45 | | |||
54 | using namespace Konsole; | 46 | using namespace Konsole; | ||
55 | 47 | | |||
56 | ViewContainer::ViewContainer(NavigationPosition position, QObject *parent) : | 48 | TabbedViewContainer::TabbedViewContainer(ViewManager *connectedViewManager, QWidget *parent) : | ||
57 | QObject(parent), | 49 | QTabWidget(parent), | ||
58 | _navigationVisibility(AlwaysShowNavigation), | 50 | _connectedViewManager(connectedViewManager) | ||
59 | _navigationPosition(position), | | |||
60 | _views(QList<QWidget *>()), | | |||
61 | _navigation(QHash<QWidget *, ViewProperties *>()), | | |||
62 | _features(nullptr), | | |||
63 | _searchBar(nullptr) | | |||
64 | { | 51 | { | ||
65 | } | 52 | tabBar()->setContextMenuPolicy(Qt::CustomContextMenu); | ||
66 | 53 | | |||
67 | ViewContainer::~ViewContainer() | 54 | connect(tabBar(), &QTabBar::tabBarDoubleClicked, this, | ||
68 | { | 55 | &Konsole::TabbedViewContainer::tabDoubleClicked); | ||
69 | foreach (QWidget *view, _views) { | 56 | connect(tabBar(), &QTabBar::customContextMenuRequested, this, | ||
70 | disconnect(view, &QWidget::destroyed, this, &Konsole::ViewContainer::viewDestroyed); | 57 | &Konsole::TabbedViewContainer::openTabContextMenu); | ||
71 | } | | |||
72 | 58 | | |||
73 | if (_searchBar != nullptr) { | 59 | // The context menu of tab bar | ||
74 | _searchBar->deleteLater(); | 60 | _contextPopupMenu = new QMenu(tabBar()); | ||
61 | connect(_contextPopupMenu, &QMenu::aboutToHide, this, [this]() { | ||||
62 | // Remove the read-only action when the popup closes | ||||
63 | for (auto &action : _contextPopupMenu->actions()) { | ||||
sandsmark: I'm not sure if konsole follows the kdelibs/qt coding style guidelines, but in case it does… | |||||
We have some 'auto' in the code before this one so I used here. the kdelibs coding style was written before C++11, perhaps we should update it for future generations. I don't use auto where the type is ambiguous or when it's impossible for the human eye to know what's the type, but since here it's an list-of-actions, it's easy to see that auto will be a QAction*. tcanabrava: We have some 'auto' in the code before this one so I used here. the kdelibs coding style was… | |||||
64 | if (action->objectName() == QStringLiteral("view-readonly")) { | ||||
65 | _contextPopupMenu->removeAction(action); | ||||
66 | break; | ||||
75 | } | 67 | } | ||
76 | | ||||
77 | emit destroyed(this); | | |||
78 | } | 68 | } | ||
69 | }); | ||||
79 | 70 | | |||
80 | void ViewContainer::moveViewWidget(int, int) | 71 | #if defined(ENABLE_DETACHING) | ||
81 | { | 72 | // _contextPopupMenu->addAction(QIcon::fromTheme(QStringLiteral("tab-detach")), | ||
73 | // i18nc("@action:inmenu", "&Detach Tab"), this, | ||||
74 | // SLOT(tabContextMenuDetachTab())); | ||||
75 | #endif | ||||
sandsmark: remove dead code | |||||
76 | | ||||
77 | _contextPopupMenu->addAction(QIcon::fromTheme(QStringLiteral("edit-rename")), | ||||
78 | i18nc("@action:inmenu", "&Rename Tab..."), this, | ||||
79 | SLOT(tabContextMenuRenameTab())); | ||||
80 | const auto contextPopupMenuActions = _contextPopupMenu->actions(); | ||||
81 | contextPopupMenuActions.last()->setObjectName(QStringLiteral("edit-rename")); | ||||
82 | | ||||
83 | auto profileMenu = new QMenu(); | ||||
84 | auto profileList = new ProfileList(false, profileMenu); | ||||
85 | profileList->syncWidgetActions(profileMenu, true); | ||||
86 | connect(profileList, &Konsole::ProfileList::profileSelected, this, | ||||
87 | static_cast<void (TabbedViewContainer::*)(Profile::Ptr)>(&Konsole::TabbedViewContainer::newViewRequest)); | ||||
88 | // setNewViewMenu(profileMenu); | ||||
sandsmark: again, breaks selecting the new profile when opening a tab. | |||||
sandsmark: maybe use qOverload instead of the ugly static_cast? | |||||
qOverload needs C++14, konsole is being compiled currently with C++11 - if you are ok with that I can enable C++ 14 for it. tcanabrava: qOverload needs C++14, konsole is being compiled currently with C++11 - if you are ok with that… | |||||
82 | } | 89 | } | ||
83 | 90 | | |||
84 | void ViewContainer::setFeatures(Features features) | 91 | TabbedViewContainer::~TabbedViewContainer() | ||
85 | { | 92 | { | ||
86 | _features = features; | 93 | for(int i = 0, end = count(); i < end; i++) { | ||
94 | auto view = widget(i); | ||||
sandsmark: same with qt coding style and auto | |||||
95 | disconnect(view, &QWidget::destroyed, this, &Konsole::TabbedViewContainer::viewDestroyed); | ||||
87 | } | 96 | } | ||
88 | 97 | | |||
89 | ViewContainer::Features ViewContainer::features() const | 98 | emit destroyed(this); | ||
90 | { | | |||
91 | return _features; | | |||
92 | } | 99 | } | ||
93 | 100 | | |||
94 | void ViewContainer::moveActiveView(MoveDirection direction) | 101 | void TabbedViewContainer::moveActiveView(MoveDirection direction) | ||
95 | { | 102 | { | ||
96 | const int currentIndex = _views.indexOf(activeView()); | 103 | const int currentIndex = indexOf(currentWidget()); | ||
97 | int newIndex = -1; | 104 | int newIndex = -1; | ||
98 | 105 | | |||
99 | switch (direction) { | 106 | switch (direction) { | ||
100 | case MoveViewLeft: | 107 | case MoveViewLeft: | ||
101 | newIndex = qMax(currentIndex - 1, 0); | 108 | newIndex = qMax(currentIndex - 1, 0); | ||
102 | break; | 109 | break; | ||
103 | case MoveViewRight: | 110 | case MoveViewRight: | ||
104 | newIndex = qMin(currentIndex + 1, _views.count() - 1); | 111 | newIndex = qMin(currentIndex + 1, count() - 1); | ||
105 | break; | 112 | break; | ||
106 | } | 113 | } | ||
107 | 114 | | |||
108 | Q_ASSERT(newIndex != -1); | 115 | Q_ASSERT(newIndex != -1); | ||
109 | 116 | auto swappedWidget = widget(newIndex); | |||
110 | moveViewWidget(currentIndex, newIndex); | 117 | auto currentWidget = widget(currentIndex); | ||
sandsmark: same issues with auto wrt. qt coding style | |||||
111 | 118 | removeTab(newIndex); | |||
112 | _views.swap(currentIndex, newIndex); | 119 | removeTab(currentIndex); | ||
113 | | ||||
114 | setActiveView(_views[newIndex]); | | |||
115 | } | | |||
116 | | ||||
117 | void ViewContainer::setNavigationVisibility(NavigationVisibility mode) | | |||
118 | { | | |||
119 | _navigationVisibility = mode; | | |||
120 | navigationVisibilityChanged(mode); | | |||
121 | } | | |||
122 | | ||||
123 | ViewContainer::NavigationPosition ViewContainer::navigationPosition() const | | |||
124 | { | | |||
125 | return _navigationPosition; | | |||
126 | } | 120 | } | ||
127 | 121 | | |||
128 | void ViewContainer::setNavigationPosition(NavigationPosition position) | 122 | void TabbedViewContainer::addView(QWidget *view, ViewProperties *item, int index) | ||
sandsmark: the «put new tab after current tab» seems to also be broken. | |||||
129 | { | | |||
130 | // assert that this position is supported | | |||
131 | Q_ASSERT(supportedNavigationPositions().contains(position)); | | |||
132 | | ||||
133 | _navigationPosition = position; | | |||
134 | | ||||
135 | navigationPositionChanged(position); | | |||
136 | } | | |||
137 | | ||||
138 | QList<ViewContainer::NavigationPosition> ViewContainer::supportedNavigationPositions() const | | |||
139 | { | | |||
140 | return QList<NavigationPosition>() << NavigationPositionTop; | | |||
141 | } | | |||
142 | | ||||
143 | void ViewContainer::setNavigationTabWidthExpanding(bool expand) | | |||
144 | { | | |||
145 | navigationTabWidthExpandingChanged(expand); | | |||
146 | } | | |||
147 | | ||||
148 | ViewContainer::NavigationVisibility ViewContainer::navigationVisibility() const | | |||
149 | { | | |||
150 | return _navigationVisibility; | | |||
151 | } | | |||
152 | | ||||
153 | void ViewContainer::setNavigationTextMode(bool mode) | | |||
154 | { | | |||
155 | navigationTextModeChanged(mode); | | |||
156 | } | | |||
157 | | ||||
158 | void ViewContainer::addView(QWidget *view, ViewProperties *item, int index) | | |||
159 | { | 123 | { | ||
160 | if (index == -1) { | 124 | if (index == -1) { | ||
161 | _views.append(view); | 125 | addTab(view, item->icon(), item->title()); | ||
162 | } else { | 126 | } else { | ||
163 | _views.insert(index, view); | 127 | insertTab(index, view, item->icon(), item->title()); | ||
164 | } | 128 | } | ||
165 | 129 | | |||
166 | _navigation[view] = item; | 130 | _navigation[view] = item; | ||
167 | 131 | connect(view, &QWidget::destroyed, this, &Konsole::TabbedViewContainer::viewDestroyed); | |||
168 | connect(view, &QWidget::destroyed, this, &Konsole::ViewContainer::viewDestroyed); | | |||
169 | | ||||
170 | addViewWidget(view, index); | | |||
171 | | ||||
172 | emit viewAdded(view, item); | 132 | emit viewAdded(view, item); | ||
173 | } | 133 | } | ||
174 | 134 | | |||
175 | void ViewContainer::viewDestroyed(QObject *view) | 135 | void TabbedViewContainer::viewDestroyed(QObject *view) | ||
176 | { | 136 | { | ||
177 | QWidget *widget = qobject_cast<QWidget *>(view); | 137 | QWidget *widget = qobject_cast<QWidget *>(view); | ||
178 | forgetView(widget); | 138 | forgetView(widget); | ||
179 | } | 139 | } | ||
180 | 140 | | |||
181 | void ViewContainer::forgetView(QWidget *view) | 141 | void TabbedViewContainer::forgetView(QWidget *view) | ||
182 | { | 142 | { | ||
183 | _views.removeAll(view); | | |||
184 | _navigation.remove(view); | 143 | _navigation.remove(view); | ||
185 | | ||||
186 | emit viewRemoved(view); | 144 | emit viewRemoved(view); | ||
187 | 145 | if (count() == 0) { | |||
188 | if (_views.count() == 0) { | | |||
189 | emit empty(this); | 146 | emit empty(this); | ||
190 | } | 147 | } | ||
191 | } | 148 | } | ||
192 | 149 | | |||
193 | void ViewContainer::removeView(QWidget *view) | 150 | void TabbedViewContainer::removeView(QWidget *view) | ||
194 | { | 151 | { | ||
195 | disconnect(view, &QWidget::destroyed, this, &Konsole::ViewContainer::viewDestroyed); | 152 | const int idx = indexOf(view); | ||
196 | removeViewWidget(view); | 153 | disconnect(view, &QWidget::destroyed, this, &Konsole::TabbedViewContainer::viewDestroyed); | ||
154 | removeTab(idx); | ||||
197 | forgetView(view); | 155 | forgetView(view); | ||
sandsmark: extremely minor coding style nitpick, avoid abbreviations. | |||||
198 | } | 156 | } | ||
199 | 157 | | |||
200 | const QList<QWidget *> ViewContainer::views() const | 158 | void TabbedViewContainer::activateNextView() | ||
201 | { | | |||
202 | return _views; | | |||
203 | } | | |||
204 | | ||||
205 | IncrementalSearchBar *ViewContainer::searchBar() | | |||
206 | { | 159 | { | ||
207 | if (_searchBar == nullptr) { | 160 | QWidget *active = currentWidget(); | ||
208 | _searchBar = new IncrementalSearchBar(nullptr); | 161 | int index = indexOf(active); | ||
209 | _searchBar->setVisible(false); | 162 | setCurrentIndex(index == count() - 1 ? 0 : index + 1); | ||
in case konsole is the opposite of the qt coding style wrt. auto this should also be auto, I guess. sandsmark: in case konsole is the opposite of the qt coding style wrt. auto this should also be auto, I… | |||||
210 | connect(_searchBar, &Konsole::IncrementalSearchBar::destroyed, this, | | |||
211 | &Konsole::ViewContainer::searchBarDestroyed); | | |||
212 | } | | |||
213 | return _searchBar; | | |||
214 | } | 163 | } | ||
215 | 164 | | |||
216 | void ViewContainer::searchBarDestroyed() | 165 | void TabbedViewContainer::activateLastView() | ||
217 | { | 166 | { | ||
218 | _searchBar = nullptr; | 167 | setCurrentIndex(count() - 1); | ||
219 | } | 168 | } | ||
220 | 169 | | |||
221 | void ViewContainer::activateNextView() | 170 | void TabbedViewContainer::activatePreviousView() | ||
222 | { | 171 | { | ||
223 | QWidget *active = activeView(); | 172 | QWidget *active = currentWidget(); | ||
224 | 173 | int index = indexOf(active); | |||
225 | int index = _views.indexOf(active); | 174 | setCurrentIndex(index == 0 ? count() - 1 : index - 1); | ||
226 | | ||||
227 | if (index == -1) { | | |||
228 | return; | | |||
229 | } | | |||
230 | | ||||
231 | if (index == _views.count() - 1) { | | |||
232 | index = 0; | | |||
233 | } else { | | |||
234 | index++; | | |||
235 | } | | |||
236 | | ||||
237 | setActiveView(_views.at(index)); | | |||
238 | } | | |||
239 | | ||||
240 | void ViewContainer::activateLastView() | | |||
241 | { | | |||
242 | setActiveView(_views.at(_views.count() - 1)); | | |||
243 | } | | |||
244 | | ||||
245 | void ViewContainer::activatePreviousView() | | |||
246 | { | | |||
247 | QWidget *active = activeView(); | | |||
248 | | ||||
249 | int index = _views.indexOf(active); | | |||
250 | | ||||
251 | if (index == -1) { | | |||
252 | return; | | |||
253 | } | | |||
254 | | ||||
255 | if (index == 0) { | | |||
256 | index = _views.count() - 1; | | |||
257 | } else { | | |||
258 | index--; | | |||
259 | } | | |||
260 | | ||||
261 | setActiveView(_views.at(index)); | | |||
262 | } | 175 | } | ||
263 | 176 | | |||
264 | ViewProperties *ViewContainer::viewProperties(QWidget *view) const | 177 | ViewProperties *TabbedViewContainer::viewProperties(QWidget *view) const | ||
265 | { | 178 | { | ||
266 | Q_ASSERT(_navigation.contains(view)); | 179 | Q_ASSERT(_navigation.contains(view)); | ||
267 | | ||||
268 | return _navigation[view]; | 180 | return _navigation[view]; | ||
269 | } | 181 | } | ||
270 | 182 | | |||
271 | QList<QWidget *> ViewContainer::widgetsForItem(ViewProperties *item) const | 183 | QList<QWidget *> TabbedViewContainer::widgetsForItem(ViewProperties *item) const | ||
272 | { | 184 | { | ||
273 | return _navigation.keys(item); | 185 | return _navigation.keys(item); | ||
274 | } | 186 | } | ||
275 | 187 | | |||
276 | TabbedViewContainer::TabbedViewContainer(NavigationPosition position, | | |||
277 | ViewManager *connectedViewManager, QObject *parent) : | | |||
278 | ViewContainer(position, parent), | | |||
279 | _tabBar(nullptr), | | |||
280 | _stackWidget(nullptr), | | |||
281 | _containerWidget(nullptr), | | |||
282 | _connectedViewManager(connectedViewManager), | | |||
283 | _layout(nullptr), | | |||
284 | _tabBarLayout(nullptr), | | |||
285 | _newTabButton(nullptr), | | |||
for some reason phabricator doesn't seem to show the patch correctly, but looking at the diff in git a new newtabbutton was added. but the new button isn't laid out properly (tiny and top-aligned). sandsmark: for some reason phabricator doesn't seem to show the patch correctly, but looking at the diff… | |||||
This is probably a issue with Qt as this method is from the QTabBar. Can you show a picture as in mine it looks correct so I can see what I can do? tcanabrava: This is probably a issue with Qt as this method is from the QTabBar. Can you show a picture as… | |||||
286 | _closeTabButton(nullptr), | | |||
287 | _contextMenuTabIndex(0), | | |||
288 | _contextPopupMenu(nullptr) | | |||
289 | { | | |||
290 | _containerWidget = new QWidget; | | |||
291 | _stackWidget = new QStackedWidget(); | | |||
292 | connect(_stackWidget.data(), &QStackedWidget::widgetRemoved, this, | | |||
293 | &TabbedViewContainer::widgetRemoved); | | |||
294 | | ||||
295 | // The tab bar | | |||
296 | _tabBar = new ViewContainerTabBar(_containerWidget, this); | | |||
297 | _tabBar->setContextMenuPolicy(Qt::CustomContextMenu); | | |||
298 | _tabBar->setSupportedMimeType(ViewProperties::mimeType()); | | |||
299 | | ||||
300 | connect(_tabBar, &Konsole::ViewContainerTabBar::currentChanged, this, | | |||
301 | &Konsole::TabbedViewContainer::currentTabChanged); | | |||
302 | connect(_tabBar, &Konsole::ViewContainerTabBar::tabBarDoubleClicked, this, | | |||
303 | &Konsole::TabbedViewContainer::tabDoubleClicked); | | |||
304 | connect(_tabBar, &Konsole::ViewContainerTabBar::querySourceIndex, this, | | |||
305 | &Konsole::TabbedViewContainer::querySourceIndex); | | |||
306 | connect(_tabBar, &Konsole::ViewContainerTabBar::moveViewRequest, this, | | |||
307 | &Konsole::TabbedViewContainer::onMoveViewRequest); | | |||
308 | connect(_tabBar, &Konsole::ViewContainerTabBar::customContextMenuRequested, this, | | |||
309 | &Konsole::TabbedViewContainer::openTabContextMenu); | | |||
310 | | ||||
311 | connect(_tabBar, &Konsole::ViewContainerTabBar::initiateDrag, this, | | |||
312 | &Konsole::TabbedViewContainer::startTabDrag); | | |||
313 | | ||||
314 | // The context menu of tab bar | | |||
315 | _contextPopupMenu = new QMenu(_tabBar); | | |||
316 | connect(_contextPopupMenu, &QMenu::aboutToHide, this, [this]() { | | |||
317 | // Remove the read-only action when the popup closes | | |||
318 | for (auto &action : _contextPopupMenu->actions()) { | | |||
319 | if (action->objectName() == QStringLiteral("view-readonly")) { | | |||
320 | _contextPopupMenu->removeAction(action); | | |||
321 | break; | | |||
322 | } | | |||
323 | } | | |||
324 | }); | | |||
325 | | ||||
326 | #if defined(ENABLE_DETACHING) | | |||
327 | _contextPopupMenu->addAction(QIcon::fromTheme(QStringLiteral("tab-detach")), | | |||
328 | i18nc("@action:inmenu", "&Detach Tab"), this, | | |||
329 | SLOT(tabContextMenuDetachTab())); | | |||
330 | #endif | | |||
331 | | ||||
332 | _contextPopupMenu->addAction(QIcon::fromTheme(QStringLiteral("edit-rename")), | | |||
333 | i18nc("@action:inmenu", "&Rename Tab..."), this, | | |||
334 | SLOT(tabContextMenuRenameTab())); | | |||
335 | const auto contextPopupMenuActions = _contextPopupMenu->actions(); | | |||
336 | contextPopupMenuActions.last()->setObjectName(QStringLiteral("edit-rename")); | | |||
337 | | ||||
338 | _contextPopupMenu->addSeparator(); | | |||
339 | | ||||
340 | _contextPopupMenu->addAction(QIcon::fromTheme(QStringLiteral("tab-close")), | | |||
341 | i18nc("@action:inmenu", "&Close Tab"), this, | | |||
342 | SLOT(tabContextMenuCloseTab())); | | |||
343 | // The 'new tab' and 'close tab' button | | |||
344 | _newTabButton = new QToolButton(_containerWidget); | | |||
345 | _newTabButton->setFocusPolicy(Qt::NoFocus); | | |||
346 | _newTabButton->setIcon(QIcon::fromTheme(QStringLiteral("tab-new"))); | | |||
347 | _newTabButton->setToolTip(i18nc("@info:tooltip", "Create new tab")); | | |||
348 | _newTabButton->setWhatsThis(i18nc("@info:whatsthis", | | |||
349 | "Create a new tab. Press and hold to select profile from menu")); | | |||
350 | _newTabButton->adjustSize(); | | |||
351 | | ||||
352 | auto profileMenu = new QMenu(_newTabButton); | | |||
353 | auto profileList = new ProfileList(false, profileMenu); | | |||
354 | profileList->syncWidgetActions(profileMenu, true); | | |||
355 | connect(profileList, &Konsole::ProfileList::profileSelected, this, | | |||
356 | static_cast<void (TabbedViewContainer::*)(Profile::Ptr)>(&Konsole::TabbedViewContainer:: | | |||
357 | newViewRequest)); | | |||
358 | setNewViewMenu(profileMenu); | | |||
359 | | ||||
360 | _closeTabButton = new QToolButton(_containerWidget); | | |||
361 | _closeTabButton->setFocusPolicy(Qt::NoFocus); | | |||
362 | _closeTabButton->setIcon(QIcon::fromTheme(QStringLiteral("tab-close"))); | | |||
363 | _closeTabButton->setToolTip(i18nc("@info:tooltip", "Close tab")); | | |||
364 | _closeTabButton->setWhatsThis(i18nc("@info:whatsthis", "Close the active tab")); | | |||
365 | _closeTabButton->adjustSize(); | | |||
366 | | ||||
367 | // 'new tab' button is initially hidden. It will be shown when setFeatures() | | |||
368 | // is called with the QuickNewView flag enabled. The 'close tab' is the same. | | |||
369 | _newTabButton->setHidden(true); | | |||
370 | _closeTabButton->setHidden(true); | | |||
371 | | ||||
372 | connect(_newTabButton, &QToolButton::clicked, this, | | |||
373 | static_cast<void (TabbedViewContainer::*)()>(&Konsole::TabbedViewContainer::newViewRequest)); | | |||
374 | connect(_closeTabButton, &QToolButton::clicked, this, | | |||
375 | &Konsole::TabbedViewContainer::closeCurrentTab); | | |||
376 | | ||||
377 | // Combine tab bar and 'new/close tab' buttons | | |||
378 | _tabBarLayout = new QHBoxLayout; | | |||
379 | _tabBarLayout->setSpacing(0); | | |||
380 | _tabBarLayout->setContentsMargins(0, 0, 0, 0); | | |||
381 | _tabBarLayout->addWidget(_newTabButton); | | |||
382 | _tabBarLayout->addWidget(_tabBar); | | |||
383 | _tabBarLayout->addWidget(_closeTabButton); | | |||
384 | | ||||
385 | // The search bar | | |||
386 | searchBar()->setParent(_containerWidget); | | |||
387 | | ||||
388 | // The overall layout | | |||
389 | _layout = new QVBoxLayout; | | |||
390 | _layout->setSpacing(0); | | |||
391 | _layout->setContentsMargins(0, 0, 0, 0); | | |||
392 | | ||||
393 | setNavigationPosition(position); | | |||
394 | | ||||
395 | _containerWidget->setLayout(_layout); | | |||
396 | } | | |||
397 | | ||||
398 | void TabbedViewContainer::setNewViewMenu(QMenu *menu) | | |||
399 | { | | |||
400 | _newTabButton->setMenu(menu); | | |||
401 | } | | |||
402 | | ||||
403 | ViewContainer::Features TabbedViewContainer::supportedFeatures() const | | |||
404 | { | | |||
405 | return QuickNewView | QuickCloseView; | | |||
406 | } | | |||
407 | | ||||
408 | void TabbedViewContainer::setFeatures(Features features) | | |||
409 | { | | |||
410 | ViewContainer::setFeatures(features); | | |||
411 | updateVisibilityOfQuickButtons(); | | |||
412 | } | | |||
413 | | ||||
414 | void TabbedViewContainer::closeCurrentTab() | 188 | void TabbedViewContainer::closeCurrentTab() | ||
415 | { | 189 | { | ||
416 | if (_stackWidget->currentIndex() != -1) { | 190 | if (currentIndex() != -1) { | ||
417 | emit closeTab(this, _stackWidget->widget(_stackWidget->currentIndex())); | 191 | emit closeTab(this, widget(currentIndex())); | ||
418 | } | | |||
419 | } | | |||
420 | | ||||
421 | void TabbedViewContainer::updateVisibilityOfQuickButtons() | | |||
422 | { | | |||
423 | const bool tabBarHidden = _tabBar->isHidden(); | | |||
424 | _newTabButton->setVisible(!tabBarHidden && ((features() & QuickNewView) != 0)); | | |||
425 | _closeTabButton->setVisible(!tabBarHidden && ((features() & QuickCloseView) != 0)); | | |||
426 | } | | |||
427 | | ||||
428 | void TabbedViewContainer::setTabBarVisible(bool visible) | | |||
429 | { | | |||
430 | _tabBar->setVisible(visible); | | |||
431 | updateVisibilityOfQuickButtons(); | | |||
432 | } | | |||
433 | | ||||
434 | QList<ViewContainer::NavigationPosition> TabbedViewContainer::supportedNavigationPositions() const | | |||
435 | { | | |||
436 | return QList<NavigationPosition>() << NavigationPositionTop << NavigationPositionBottom; | | |||
437 | } | | |||
438 | | ||||
439 | void TabbedViewContainer::navigationPositionChanged(NavigationPosition position) | | |||
440 | { | | |||
441 | // this method assumes that there are three or zero items in the layout | | |||
442 | Q_ASSERT(_layout->count() == 3 || _layout->count() == 0); | | |||
443 | | ||||
444 | // clear all existing items from the layout | | |||
445 | _layout->removeItem(_tabBarLayout); | | |||
446 | _tabBarLayout->setParent(nullptr); // suppress the warning of "already has a parent" | | |||
447 | _layout->removeWidget(_stackWidget); | | |||
448 | _layout->removeWidget(searchBar()); | | |||
449 | | ||||
450 | if (position == NavigationPositionTop) { | | |||
451 | _layout->insertLayout(-1, _tabBarLayout); | | |||
452 | _layout->insertWidget(-1, _stackWidget); | | |||
453 | _layout->insertWidget(-1, searchBar()); | | |||
454 | _tabBar->setShape(QTabBar::RoundedNorth); | | |||
455 | } else if (position == NavigationPositionBottom) { | | |||
456 | _layout->insertWidget(-1, _stackWidget); | | |||
457 | _layout->insertWidget(-1, searchBar()); | | |||
458 | _layout->insertLayout(-1, _tabBarLayout); | | |||
459 | _tabBar->setShape(QTabBar::RoundedSouth); | | |||
460 | } else { | | |||
461 | Q_ASSERT(false); // should never reach here | | |||
462 | } | | |||
463 | } | | |||
464 | | ||||
465 | void TabbedViewContainer::navigationTabWidthExpandingChanged(bool expand) | | |||
466 | { | | |||
467 | _tabBar->setExpanding(expand); | | |||
468 | } | 192 | } | ||
469 | | ||||
470 | void TabbedViewContainer::navigationVisibilityChanged(NavigationVisibility mode) | | |||
471 | { | | |||
472 | if (mode == AlwaysShowNavigation && _tabBar->isHidden()) { | | |||
473 | setTabBarVisible(true); | | |||
474 | } | | |||
475 | | ||||
476 | if (mode == AlwaysHideNavigation && !_tabBar->isHidden()) { | | |||
477 | setTabBarVisible(false); | | |||
478 | } | | |||
479 | | ||||
480 | if (mode == ShowNavigationAsNeeded) { | | |||
481 | dynamicTabBarVisibility(); | | |||
482 | } | | |||
483 | } | | |||
484 | | ||||
485 | void TabbedViewContainer::dynamicTabBarVisibility() | | |||
486 | { | | |||
487 | if (_tabBar->count() > 1 && _tabBar->isHidden()) { | | |||
488 | setTabBarVisible(true); | | |||
489 | } | | |||
490 | | ||||
491 | if (_tabBar->count() < 2 && !_tabBar->isHidden()) { | | |||
492 | setTabBarVisible(false); | | |||
493 | } | | |||
494 | } | | |||
495 | | ||||
496 | void TabbedViewContainer::setStyleSheet(const QString &styleSheet) | | |||
497 | { | | |||
498 | _tabBar->setStyleSheet(styleSheet); | | |||
499 | } | | |||
500 | | ||||
501 | // TODO: Only called via dbus method - remove | | |||
502 | void TabbedViewContainer::navigationTextModeChanged(bool useTextWidth) | | |||
503 | { | | |||
504 | // Qt 5.9 changed how tabs are displayed | | |||
505 | if (useTextWidth) { | | |||
506 | _tabBar->setStyleSheet(QStringLiteral("QTabBar::tab { }")); | | |||
507 | _tabBar->setExpanding(false); | | |||
508 | _tabBar->setElideMode(Qt::ElideNone); | | |||
509 | } else { | | |||
510 | _tabBar->setStyleSheet(QStringLiteral("QTabBar::tab { min-width: 2em; max-width: 25em }")); | | |||
511 | _tabBar->setExpanding(true); | | |||
512 | _tabBar->setElideMode(Qt::ElideLeft); | | |||
513 | } | | |||
514 | } | | |||
515 | | ||||
516 | TabbedViewContainer::~TabbedViewContainer() | | |||
517 | { | | |||
518 | if (!_containerWidget.isNull()) { | | |||
519 | _containerWidget->deleteLater(); | | |||
520 | } | | |||
521 | } | | |||
522 | | ||||
523 | void TabbedViewContainer::startTabDrag(int index) | | |||
524 | { | | |||
525 | QPointer<QDrag> drag = new QDrag(_tabBar); | | |||
526 | const QRect tabRect = _tabBar->tabRect(index); | | |||
527 | QPixmap tabPixmap = _tabBar->dragDropPixmap(index); | | |||
528 | | ||||
529 | drag->setPixmap(tabPixmap); | | |||
530 | | ||||
531 | // offset the tab position so the tab will follow the cursor exactly | | |||
532 | // where it was clicked (as opposed to centering on the origin of the pixmap) | | |||
533 | QPoint mappedPos = _tabBar->mapFromGlobal(QCursor::pos()); | | |||
534 | mappedPos.rx() -= tabRect.x(); | | |||
535 | | ||||
536 | drag->setHotSpot(mappedPos); | | |||
537 | | ||||
538 | const int id = viewProperties(views()[index])->identifier(); | | |||
539 | QWidget *view = views()[index]; | | |||
540 | drag->setMimeData(ViewProperties::createMimeData(id)); | | |||
541 | | ||||
542 | // start dragging | | |||
543 | const Qt::DropAction action = drag->exec(); | | |||
544 | | ||||
545 | if ((!drag.isNull()) && (drag->target() != nullptr)) { | | |||
546 | switch (action) { | | |||
547 | case Qt::MoveAction: | | |||
548 | // The MoveAction indicates the widget has been successfully | | |||
549 | // moved into another tabbar/container, so remove the widget in | | |||
550 | // current tabbar/container. | | |||
551 | // | | |||
552 | // Deleting the view may cause the view container to be deleted, | | |||
553 | // which will also delete the QDrag object. This can cause a | | |||
554 | // crash if Qt's internal drag-and-drop handling tries to delete | | |||
555 | // it later. | | |||
556 | // | | |||
557 | // For now set the QDrag's parent to 0 so that it won't be | | |||
558 | // deleted if this view container is destroyed. | | |||
559 | // | | |||
560 | // FIXME: Resolve this properly | | |||
561 | drag->setParent(nullptr); | | |||
562 | removeView(view); | | |||
563 | break; | | |||
564 | case Qt::IgnoreAction: | | |||
565 | // The IgnoreAction is used by the tabbar to indicate the | | |||
566 | // special case of dropping one tab into its existing position. | | |||
567 | // So nothing need to do here. | | |||
568 | break; | | |||
569 | default: | | |||
570 | break; | | |||
571 | } | | |||
572 | } else { | | |||
573 | // if the tab is dragged onto something that does not accept this | | |||
574 | // drop(for example, a different application or a different konsole | | |||
575 | // process), then detach the tab to achieve the effect of "dragging tab | | |||
576 | // out of current window and into its own window" | | |||
577 | // | | |||
578 | // It feels unnatural to do the detach when this is only one tab in the | | |||
579 | // tabbar | | |||
580 | if (_tabBar->count() > 1) { | | |||
581 | emit detachTab(this, view); | | |||
582 | } | | |||
583 | } | | |||
584 | delete drag; | | |||
585 | } | | |||
586 | | ||||
587 | void TabbedViewContainer::querySourceIndex(const QDropEvent *event, int &sourceIndex) | | |||
588 | { | | |||
589 | const int droppedId = ViewProperties::decodeMimeData(event->mimeData()); | | |||
590 | | ||||
591 | const QList<QWidget *> viewList = views(); | | |||
592 | const int count = viewList.count(); | | |||
593 | int index = -1; | | |||
594 | for (index = 0; index < count; index++) { | | |||
595 | const int id = viewProperties(viewList[index])->identifier(); | | |||
596 | if (id == droppedId) { | | |||
597 | break; | | |||
598 | } | | |||
599 | } | | |||
600 | | ||||
601 | sourceIndex = index; | | |||
602 | } | | |||
603 | | ||||
604 | void TabbedViewContainer::onMoveViewRequest(int index, const QDropEvent *event, bool &success, | | |||
605 | TabbedViewContainer *sourceTabbedContainer) | | |||
606 | { | | |||
607 | const int droppedId = ViewProperties::decodeMimeData(event->mimeData()); | | |||
608 | emit moveViewRequest(index, droppedId, success, sourceTabbedContainer); | | |||
609 | } | 193 | } | ||
610 | 194 | | |||
611 | void TabbedViewContainer::tabDoubleClicked(int index) | 195 | void TabbedViewContainer::tabDoubleClicked(int index) | ||
612 | { | 196 | { | ||
613 | if (index >= 0) { | 197 | if (index >= 0) { | ||
614 | renameTab(index); | 198 | renameTab(index); | ||
615 | } else { | 199 | } else { | ||
616 | emit newViewRequest(); | 200 | emit newViewRequest(); | ||
617 | } | 201 | } | ||
618 | } | 202 | } | ||
619 | 203 | | |||
620 | void TabbedViewContainer::renameTab(int index) | 204 | void TabbedViewContainer::renameTab(int index) | ||
621 | { | 205 | { | ||
622 | viewProperties(views()[index])->rename(); | 206 | // TODO: Fix rename. | ||
207 | // _navigation[index]->rename(); | ||||
sandsmark: outdated comment or is it broken? | |||||
tcanabrava: outdated. | |||||
623 | } | 208 | } | ||
624 | 209 | | |||
625 | void TabbedViewContainer::openTabContextMenu(const QPoint &point) | 210 | void TabbedViewContainer::openTabContextMenu(const QPoint &point) | ||
626 | { | 211 | { | ||
627 | if (point.isNull()) { | 212 | if (point.isNull()) { | ||
628 | return; | 213 | return; | ||
629 | } | 214 | } | ||
630 | 215 | | |||
631 | _contextMenuTabIndex = _tabBar->tabAt(point); | 216 | const int contextMenuTabIndex = tabBar()->tabAt(point); | ||
632 | if (_contextMenuTabIndex < 0) { | 217 | if (contextMenuTabIndex < 0) { | ||
633 | return; | 218 | return; | ||
634 | } | 219 | } | ||
635 | 220 | | |||
636 | #if defined(ENABLE_DETACHING) | 221 | #if defined(ENABLE_DETACHING) | ||
637 | // Enable 'Detach Tab' menu item only if there is more than 1 tab | 222 | // Enable 'Detach Tab' menu item only if there is more than 1 tab | ||
638 | // Note: the code is coupled with that action's position within the menu | 223 | // Note: the code is coupled with that action's position within the menu | ||
639 | QAction *detachAction = _contextPopupMenu->actions().at(0); | 224 | QAction *detachAction = _contextPopupMenu->actions().at(0); | ||
640 | detachAction->setEnabled(_tabBar->count() > 1); | 225 | detachAction->setEnabled(count() > 1); | ||
641 | #endif | 226 | #endif | ||
642 | 227 | | |||
643 | // Add the read-only action | 228 | // Add the read-only action | ||
644 | SessionController *sessionController = qobject_cast<SessionController*>(viewProperties(views()[_contextMenuTabIndex])); | 229 | auto controller = _navigation[widget(contextMenuTabIndex)]; | ||
230 | auto sessionController = qobject_cast<SessionController*>(controller); | ||||
231 | | ||||
645 | if (sessionController != nullptr) { | 232 | if (sessionController != nullptr) { | ||
646 | auto collection = sessionController->actionCollection(); | 233 | auto collection = sessionController->actionCollection(); | ||
647 | auto readonlyAction = collection->action(QStringLiteral("view-readonly")); | 234 | auto readonlyAction = collection->action(QStringLiteral("view-readonly")); | ||
648 | if (readonlyAction != nullptr) { | 235 | if (readonlyAction != nullptr) { | ||
649 | const auto readonlyActions = _contextPopupMenu->actions(); | 236 | const auto readonlyActions = _contextPopupMenu->actions(); | ||
650 | _contextPopupMenu->insertAction(readonlyActions.last(), readonlyAction); | 237 | _contextPopupMenu->insertAction(readonlyActions.last(), readonlyAction); | ||
651 | } | 238 | } | ||
652 | 239 | | |||
653 | // Disable tab rename | 240 | // Disable tab rename | ||
654 | for (auto &action : _contextPopupMenu->actions()) { | 241 | for (auto &action : _contextPopupMenu->actions()) { | ||
655 | if (action->objectName() == QStringLiteral("edit-rename")) { | 242 | if (action->objectName() == QStringLiteral("edit-rename")) { | ||
656 | action->setEnabled(!sessionController->isReadOnly()); | 243 | action->setEnabled(!sessionController->isReadOnly()); | ||
657 | break; | 244 | break; | ||
658 | } | 245 | } | ||
659 | } | 246 | } | ||
660 | } | 247 | } | ||
661 | 248 | | |||
662 | _contextPopupMenu->exec(_tabBar->mapToGlobal(point)); | 249 | _contextPopupMenu->exec(tabBar()->mapToGlobal(point)); | ||
663 | } | | |||
664 | | ||||
665 | void TabbedViewContainer::tabContextMenuCloseTab() | | |||
666 | { | | |||
667 | _tabBar->setCurrentIndex(_contextMenuTabIndex);// Required for this to work | | |||
668 | emit closeTab(this, _stackWidget->widget(_contextMenuTabIndex)); | | |||
669 | } | | |||
670 | | ||||
671 | void TabbedViewContainer::tabContextMenuDetachTab() | | |||
672 | { | | |||
673 | emit detachTab(this, _stackWidget->widget(_contextMenuTabIndex)); | | |||
674 | } | | |||
675 | | ||||
676 | void TabbedViewContainer::tabContextMenuRenameTab() | | |||
677 | { | | |||
678 | renameTab(_contextMenuTabIndex); | | |||
679 | } | | |||
680 | | ||||
681 | void TabbedViewContainer::moveViewWidget(int fromIndex, int toIndex) | | |||
682 | { | | |||
683 | QString text = _tabBar->tabText(fromIndex); | | |||
684 | QIcon icon = _tabBar->tabIcon(fromIndex); | | |||
685 | | ||||
686 | // FIXME (KF5?)- This will lose properties of the tab other than | | |||
687 | // their text and icon when moving them | | |||
688 | | ||||
689 | QWidget *widget = _stackWidget->widget(fromIndex); | | |||
690 | // this also removes the tab from the tab bar | | |||
691 | _stackWidget->removeWidget(widget); | | |||
692 | _stackWidget->insertWidget(toIndex, widget); | | |||
693 | | ||||
694 | _tabBar->insertTab(toIndex, icon, text); | | |||
695 | | ||||
696 | if (navigationVisibility() == ShowNavigationAsNeeded) { | | |||
697 | dynamicTabBarVisibility(); | | |||
698 | } | | |||
699 | } | 250 | } | ||
700 | 251 | | |||
701 | void TabbedViewContainer::currentTabChanged(int index) | 252 | void TabbedViewContainer::currentTabChanged(int index) | ||
702 | { | 253 | { | ||
703 | _stackWidget->setCurrentIndex(index); | 254 | setCurrentIndex(index); | ||
704 | if (_stackWidget->widget(index) != nullptr) { | 255 | if (widget(index) != nullptr) { | ||
705 | emit activeViewChanged(_stackWidget->widget(index)); | 256 | emit activeViewChanged(widget(index)); | ||
706 | } | 257 | } | ||
707 | 258 | | |||
708 | // clear activity indicators | 259 | // clear activity indicators | ||
709 | setTabActivity(index, false); | 260 | setTabActivity(index, false); | ||
710 | } | 261 | } | ||
711 | 262 | | |||
712 | void TabbedViewContainer::wheelScrolled(int delta) | 263 | void TabbedViewContainer::wheelScrolled(int delta) | ||
713 | { | 264 | { | ||
714 | if (delta < 0) { | 265 | if (delta < 0) { | ||
715 | activateNextView(); | 266 | activateNextView(); | ||
716 | } else { | 267 | } else { | ||
717 | activatePreviousView(); | 268 | activatePreviousView(); | ||
718 | } | 269 | } | ||
719 | } | 270 | } | ||
720 | 271 | | |||
721 | QWidget *TabbedViewContainer::containerWidget() const | | |||
722 | { | | |||
723 | return _containerWidget; | | |||
724 | } | | |||
725 | | ||||
726 | QWidget *TabbedViewContainer::activeView() const | | |||
727 | { | | |||
728 | return _stackWidget->currentWidget(); | | |||
729 | } | | |||
730 | | ||||
731 | void TabbedViewContainer::setActiveView(QWidget *view) | | |||
732 | { | | |||
733 | const int index = _stackWidget->indexOf(view); | | |||
734 | | ||||
735 | Q_ASSERT(index != -1); | | |||
736 | | ||||
737 | _stackWidget->setCurrentWidget(view); | | |||
738 | _tabBar->setCurrentIndex(index); | | |||
739 | } | | |||
740 | | ||||
741 | void TabbedViewContainer::addViewWidget(QWidget *view, int index) | 272 | void TabbedViewContainer::addViewWidget(QWidget *view, int index) | ||
742 | { | 273 | { | ||
743 | _stackWidget->insertWidget(index, view); | | |||
744 | _stackWidget->updateGeometry(); | | |||
745 | | ||||
746 | ViewProperties *item = viewProperties(view); | 274 | ViewProperties *item = viewProperties(view); | ||
747 | connect(item, &Konsole::ViewProperties::titleChanged, this, | 275 | connect(item, &Konsole::ViewProperties::titleChanged, this, | ||
748 | &Konsole::TabbedViewContainer::updateTitle); | 276 | &Konsole::TabbedViewContainer::updateTitle); | ||
749 | connect(item, &Konsole::ViewProperties::iconChanged, this, | 277 | connect(item, &Konsole::ViewProperties::iconChanged, this, | ||
750 | &Konsole::TabbedViewContainer::updateIcon); | 278 | &Konsole::TabbedViewContainer::updateIcon); | ||
751 | connect(item, &Konsole::ViewProperties::activity, this, | 279 | connect(item, &Konsole::ViewProperties::activity, this, | ||
752 | &Konsole::TabbedViewContainer::updateActivity); | 280 | &Konsole::TabbedViewContainer::updateActivity); | ||
753 | 281 | | |||
754 | _tabBar->insertTab(index, item->icon(), item->title()); | 282 | insertTab(index, view, item->icon(), item->title()); | ||
755 | | ||||
756 | if (navigationVisibility() == ShowNavigationAsNeeded) { | | |||
757 | dynamicTabBarVisibility(); | | |||
758 | } | | |||
759 | } | | |||
760 | | ||||
761 | void TabbedViewContainer::removeViewWidget(QWidget *view) | | |||
762 | { | | |||
763 | if (_stackWidget.isNull()) { | | |||
764 | return; | | |||
765 | } | | |||
766 | _stackWidget->removeWidget(view); | | |||
767 | } | | |||
768 | | ||||
769 | void TabbedViewContainer::widgetRemoved(int index) | | |||
770 | { | | |||
771 | Q_ASSERT(index != -1); | | |||
772 | | ||||
773 | _tabBar->removeTab(index); | | |||
774 | | ||||
775 | if (navigationVisibility() == ShowNavigationAsNeeded) { | | |||
776 | dynamicTabBarVisibility(); | | |||
777 | } | | |||
778 | } | 283 | } | ||
779 | 284 | | |||
780 | void TabbedViewContainer::setTabActivity(int index, bool activity) | 285 | void TabbedViewContainer::setTabActivity(int index, bool activity) | ||
781 | { | 286 | { | ||
782 | const QPalette &palette = _tabBar->palette(); | 287 | const QPalette &palette = tabBar()->palette(); | ||
783 | KColorScheme colorScheme(palette.currentColorGroup()); | 288 | KColorScheme colorScheme(palette.currentColorGroup()); | ||
784 | const QColor colorSchemeActive = colorScheme.foreground(KColorScheme::ActiveText).color(); | 289 | const QColor colorSchemeActive = colorScheme.foreground(KColorScheme::ActiveText).color(); | ||
785 | 290 | | |||
786 | const QColor normalColor = palette.text().color(); | 291 | const QColor normalColor = palette.text().color(); | ||
787 | const QColor activityColor = KColorUtils::mix(normalColor, colorSchemeActive); | 292 | const QColor activityColor = KColorUtils::mix(normalColor, colorSchemeActive); | ||
788 | 293 | | |||
789 | QColor color = activity ? activityColor : QColor(); | 294 | QColor color = activity ? activityColor : QColor(); | ||
790 | 295 | | |||
791 | if (color != _tabBar->tabTextColor(index)) { | 296 | if (color != tabBar()->tabTextColor(index)) { | ||
792 | _tabBar->setTabTextColor(index, color); | 297 | tabBar()->setTabTextColor(index, color); | ||
793 | } | 298 | } | ||
794 | } | 299 | } | ||
795 | 300 | | |||
796 | void TabbedViewContainer::updateActivity(ViewProperties *item) | 301 | void TabbedViewContainer::updateActivity(ViewProperties *item) | ||
797 | { | 302 | { | ||
798 | foreach (QWidget *widget, widgetsForItem(item)) { | 303 | foreach (QWidget *widget, widgetsForItem(item)) { | ||
799 | const int index = _stackWidget->indexOf(widget); | 304 | const int index = indexOf(widget); | ||
800 | 305 | | |||
801 | if (index != _stackWidget->currentIndex()) { | 306 | if (index != currentIndex()) { | ||
802 | setTabActivity(index, true); | 307 | setTabActivity(index, true); | ||
803 | } | 308 | } | ||
804 | } | 309 | } | ||
805 | } | 310 | } | ||
806 | 311 | | |||
807 | void TabbedViewContainer::updateTitle(ViewProperties *item) | 312 | void TabbedViewContainer::updateTitle(ViewProperties *item) | ||
808 | { | 313 | { | ||
809 | foreach (QWidget *widget, widgetsForItem(item)) { | 314 | foreach (QWidget *widget, widgetsForItem(item)) { | ||
810 | const int index = _stackWidget->indexOf(widget); | 315 | const int index = indexOf(widget); | ||
811 | QString tabText = item->title(); | 316 | QString tabText = item->title(); | ||
812 | 317 | | |||
813 | _tabBar->setTabToolTip(index, tabText); | 318 | setTabToolTip(index, tabText); | ||
814 | 319 | | |||
815 | // To avoid having & replaced with _ (shortcut indicator) | 320 | // To avoid having & replaced with _ (shortcut indicator) | ||
816 | tabText.replace(QLatin1Char('&'), QLatin1String("&&")); | 321 | tabText.replace(QLatin1Char('&'), QLatin1String("&&")); | ||
817 | _tabBar->setTabText(index, tabText); | 322 | setTabText(index, tabText); | ||
818 | } | 323 | } | ||
819 | } | 324 | } | ||
820 | 325 | | |||
821 | void TabbedViewContainer::updateIcon(ViewProperties *item) | 326 | void TabbedViewContainer::updateIcon(ViewProperties *item) | ||
822 | { | 327 | { | ||
823 | foreach (QWidget *widget, widgetsForItem(item)) { | 328 | foreach (QWidget *widget, widgetsForItem(item)) { | ||
824 | const int index = _stackWidget->indexOf(widget); | 329 | const int index = indexOf(widget); | ||
825 | _tabBar->setTabIcon(index, item->icon()); | 330 | setTabIcon(index, item->icon()); | ||
826 | } | 331 | } | ||
827 | } | 332 | } | ||
828 | 333 | | |||
829 | ViewManager *TabbedViewContainer::connectedViewManager() | 334 | ViewManager *TabbedViewContainer::connectedViewManager() | ||
830 | { | 335 | { | ||
831 | return _connectedViewManager; | 336 | return _connectedViewManager; | ||
832 | } | 337 | } |
I'm not sure if konsole follows the kdelibs/qt coding style guidelines, but in case it does iirc auto should not be used here.