1 /*
2    SPDX-FileCopyrightText: 2013-2021 Laurent Montel <montel@kde.org>
3 
4    SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6 #include "sieveeditortabwidget.h"
7 #include "webengine/sieveeditorhelphtmlwidget.h"
8 
9 #include <KLocalizedString>
10 #include <KStringHandler>
11 
12 #include <QMenu>
13 #include <QTabBar>
14 #include <QUrl>
15 
16 using namespace KSieveUi;
SieveEditorTabWidget(QWidget * parent)17 SieveEditorTabWidget::SieveEditorTabWidget(QWidget *parent)
18     : QTabWidget(parent)
19 {
20     setTabsClosable(true);
21     connect(this, &SieveEditorTabWidget::tabCloseRequested, this, &SieveEditorTabWidget::slotTabCloseRequested);
22     setContextMenuPolicy(Qt::CustomContextMenu);
23     connect(this, &SieveEditorTabWidget::customContextMenuRequested, this, &SieveEditorTabWidget::slotTabContextMenuRequest);
24 }
25 
~SieveEditorTabWidget()26 SieveEditorTabWidget::~SieveEditorTabWidget()
27 {
28 }
29 
slotTabContextMenuRequest(const QPoint & pos)30 void SieveEditorTabWidget::slotTabContextMenuRequest(const QPoint &pos)
31 {
32     QTabBar *bar = tabBar();
33     if (count() <= 1) {
34         return;
35     }
36 
37     const int indexBar = bar->tabAt(bar->mapFrom(this, pos));
38     if (indexBar == -1) {
39         return;
40     }
41     QMenu menu(this);
42 
43     const int countTab = (count() > 1);
44 
45     QAction *closeTab = nullptr;
46     if ((indexBar != 0) && countTab) {
47         closeTab = menu.addAction(i18nc("@action:inmenu", "Close Tab"));
48         closeTab->setIcon(QIcon::fromTheme(QStringLiteral("tab-close")));
49     }
50 
51     QAction *allOther = nullptr;
52     if ((indexBar == 0) || (count() > 2)) {
53         allOther = menu.addAction(i18nc("@action:inmenu", "Close All Other Tabs"));
54         allOther->setIcon(QIcon::fromTheme(QStringLiteral("tab-close-other")));
55     }
56 
57     QAction *allTab = nullptr;
58     if (countTab) {
59         allTab = menu.addAction(i18nc("@action:inmenu", "Close All Tabs"));
60         allTab->setEnabled(countTab);
61         allTab->setIcon(QIcon::fromTheme(QStringLiteral("tab-close")));
62     }
63 
64     QAction *action = menu.exec(mapToGlobal(pos));
65 
66     if (action) {
67         if (action == allOther) { // Close all other tabs
68             slotCloseAllTabExcept(indexBar);
69         } else if (action == closeTab) {
70             slotCloseRequest(indexBar);
71         } else if (action == allTab) {
72             slotCloseAllTab();
73         }
74     }
75 }
76 
slotCloseRequest(int index)77 void SieveEditorTabWidget::slotCloseRequest(int index)
78 {
79     if (index != 0) {
80         removeTab(index);
81     }
82 }
83 
closeAllTabExcept(int index)84 void SieveEditorTabWidget::closeAllTabExcept(int index)
85 {
86     // Don't close first tab
87     for (int i = count() - 1; i > 0; --i) {
88         if (i == index) {
89             continue;
90         }
91         removeTab(i);
92     }
93 }
94 
slotCloseAllTabExcept(int index)95 void SieveEditorTabWidget::slotCloseAllTabExcept(int index)
96 {
97     closeAllTabExcept(index);
98 }
99 
slotCloseAllTab()100 void SieveEditorTabWidget::slotCloseAllTab()
101 {
102     closeAllTabExcept();
103 }
104 
slotTabCloseRequested(int index)105 void SieveEditorTabWidget::slotTabCloseRequested(int index)
106 {
107     // Don't remove first tab.
108     if (index > 0) {
109         removeTab(index);
110     }
111 }
112 
currentPageIsHtmlPage() const113 bool SieveEditorTabWidget::currentPageIsHtmlPage() const
114 {
115     auto page = qobject_cast<SieveEditorHelpHtmlWidget *>(currentWidget());
116     return page ? true : false;
117 }
118 
currentHelpUrl() const119 QUrl SieveEditorTabWidget::currentHelpUrl() const
120 {
121     auto page = qobject_cast<SieveEditorHelpHtmlWidget *>(currentWidget());
122     if (page) {
123         return page->currentUrl();
124     }
125     return QUrl();
126 }
127 
currentHelpTitle() const128 QString SieveEditorTabWidget::currentHelpTitle() const
129 {
130     auto page = qobject_cast<SieveEditorHelpHtmlWidget *>(currentWidget());
131     if (page) {
132         return page->title();
133     }
134     return QString();
135 }
136 
slotAddHelpPage(const QUrl & url)137 void SieveEditorTabWidget::slotAddHelpPage(const QUrl &url)
138 {
139     for (int i = 0; i < count(); ++i) {
140         auto page = qobject_cast<SieveEditorHelpHtmlWidget *>(widget(i));
141         if (page && page->currentUrl() == url) {
142             setCurrentIndex(i);
143             return;
144         }
145     }
146     auto htmlPage = new SieveEditorHelpHtmlWidget;
147     connect(htmlPage, &SieveEditorHelpHtmlWidget::titleChanged, this, &SieveEditorTabWidget::slotTitleChanged);
148     connect(htmlPage, &SieveEditorHelpHtmlWidget::progressIndicatorPixmapChanged, this, &SieveEditorTabWidget::slotProgressIndicatorPixmapChanged);
149     connect(htmlPage, &SieveEditorHelpHtmlWidget::loadFinished, this, &SieveEditorTabWidget::slotLoadFinished);
150     connect(htmlPage, &SieveEditorHelpHtmlWidget::copyAvailable, this, &SieveEditorTabWidget::copyAvailable);
151     htmlPage->openUrl(url);
152     const int index = addTab(htmlPage, i18n("Help"));
153     setCurrentIndex(index);
154 }
155 
slotLoadFinished(KSieveUi::SieveEditorHelpHtmlWidget * widget,bool success)156 void SieveEditorTabWidget::slotLoadFinished(KSieveUi::SieveEditorHelpHtmlWidget *widget, bool success)
157 {
158     const int index = indexOf(widget);
159     if (index != -1) {
160         setTabIcon(index, QIcon());
161     }
162     if (!success) {
163         setTabText(index, i18n("Error during load page about %1", widget->title()));
164     }
165 }
166 
slotProgressIndicatorPixmapChanged(KSieveUi::SieveEditorHelpHtmlWidget * widget,const QPixmap & pixmap)167 void SieveEditorTabWidget::slotProgressIndicatorPixmapChanged(KSieveUi::SieveEditorHelpHtmlWidget *widget, const QPixmap &pixmap)
168 {
169     const int index = indexOf(widget);
170     if (index != -1) {
171         setTabIcon(index, QIcon(pixmap));
172     }
173 }
174 
slotTitleChanged(KSieveUi::SieveEditorHelpHtmlWidget * widget,const QString & title)175 void SieveEditorTabWidget::slotTitleChanged(KSieveUi::SieveEditorHelpHtmlWidget *widget, const QString &title)
176 {
177     const int index = indexOf(widget);
178     if (index != -1) {
179         const QString troncateTitle = KStringHandler::lsqueeze(title, 30);
180         setTabText(index, i18n("Help about: %1", troncateTitle));
181         setTabToolTip(index, title);
182     }
183 }
184 
tabRemoved(int index)185 void SieveEditorTabWidget::tabRemoved(int index)
186 {
187     if (count() <= 1) {
188         tabBar()->hide();
189     }
190     QTabWidget::tabRemoved(index);
191 }
192 
tabInserted(int index)193 void SieveEditorTabWidget::tabInserted(int index)
194 {
195     if (count() > 1) {
196         tabBar()->show();
197     }
198     QTabWidget::tabInserted(index);
199     tabBar()->tabButton(0, QTabBar::RightSide)->setEnabled(false);
200 }
201