1 //=============================================================================
2 //
3 // File : KviIrcView_tools.cpp
4 // Creation date : Sat Oct 9 2004 16:03:01 by Szymon Stefanek
5 //
6 // This file is part of the KVIrc IRC client distribution
7 // Copyright (C) 2004-2010 Szymon Stefanek (pragma at kvirc dot net)
8 //
9 // This program is FREE software. You can redistribute it and/or
10 // modify it under the terms of the GNU General Public License
11 // as published by the Free Software Foundation; either version 2
12 // of the License, or (at your option) any later version.
13 //
14 // This program is distributed in the HOPE that it will be USEFUL,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 // See the GNU General Public License for more details.
18 //
19 // You should have received a copy of the GNU General Public License
20 // along with this program. If not, write to the Free Software Foundation,
21 // Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 //
23 //=============================================================================
24
25 #include "KviIrcView_tools.h"
26 #include "KviIrcView.h"
27 #include "KviIconManager.h"
28 #include "KviOptions.h"
29 #include "KviLocale.h"
30 #include "KviMemory.h"
31 #include "KviMessageBox.h"
32 #include "KviFileDialog.h"
33 #include "KviApplication.h"
34 #include "KviThemedLineEdit.h"
35 #include "KviShortcut.h"
36 #include "KviWindow.h"
37
38 #include <QHBoxLayout>
39 #include <QLabel>
40 #include <QPushButton>
41 #include <QCursor>
42 #include <QEvent>
43 #include <QMouseEvent>
44 #include <QHeaderView>
45 #include <QScrollBar>
46 #include <QComboBox>
47 #include <QIcon>
48 #include <QMenu>
49
50 //
51 // Tool widget implementation
52 //
53
KviIrcMessageCheckListItem(QTreeWidget * par,KviIrcViewToolWidget * w,int id)54 KviIrcMessageCheckListItem::KviIrcMessageCheckListItem(QTreeWidget * par, KviIrcViewToolWidget * w, int id)
55 : QTreeWidgetItem(par)
56 {
57 m_iId = id;
58 setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable);
59 setCheckState(0, Qt::Checked);
60 setIcon(0, *(g_pIconManager->getSmallIcon(KVI_OPTION_MSGTYPE(id).pixId())));
61 setText(0, __tr2qs_no_xgettext(KVI_OPTION_MSGTYPE(id).type()));
62 m_pToolWidget = w;
63 }
64
65 KviIrcMessageCheckListItem::~KviIrcMessageCheckListItem()
66 = default;
67
KviIrcViewToolWidget(KviIrcView * pParent)68 KviIrcViewToolWidget::KviIrcViewToolWidget(KviIrcView * pParent)
69 : QWidget(pParent)
70 {
71 m_pIrcView = pParent;
72 setAutoFillBackground(true);
73 setContentsMargins(0, 0, 0, 0);
74
75 QHBoxLayout * pLayout = new QHBoxLayout(this);
76 pLayout->setMargin(2);
77 pLayout->setSpacing(2);
78
79 QPushButton * pButton = new QPushButton(QIcon(*g_pIconManager->getSmallIcon(KviIconManager::Close)), QString(), this);
80 pButton->setFixedSize(16, 16);
81 pButton->setFlat(true);
82 connect(pButton, SIGNAL(clicked()), m_pIrcView, SLOT(toggleToolWidget()));
83 pLayout->addWidget(pButton);
84
85 m_pStringToFind = new KviThemedLineEdit(this, m_pIrcView->parentKviWindow(), "search_lineedit");
86 pLayout->addWidget(m_pStringToFind);
87 connect(m_pStringToFind, SIGNAL(returnPressed()), this, SLOT(findNext()));
88 connect(m_pStringToFind, SIGNAL(textChanged(QString)), this, SLOT(findNextHelper(QString)));
89
90 pButton = new QPushButton(__tr2qs("&Next"), this);
91 pButton->setDefault(true);
92 connect(pButton, SIGNAL(clicked()), this, SLOT(findNext()));
93 pLayout->addWidget(pButton);
94
95 pButton = new QPushButton(__tr2qs("&Previous"), this);
96 connect(pButton, SIGNAL(clicked()), this, SLOT(findPrev()));
97 pLayout->addWidget(pButton);
98
99 m_pOptionsButton = new QPushButton(this);
100 m_pOptionsButton->setText(__tr2qs("&Options"));
101 pLayout->addWidget(m_pOptionsButton);
102
103 m_pOptionsWidget = new QMenu(m_pOptionsButton);
104 QGridLayout * pOptionsLayout = new QGridLayout(m_pOptionsWidget);
105 pOptionsLayout->setSpacing(2);
106
107 connect(m_pOptionsButton, SIGNAL(clicked()), this, SLOT(toggleOptions()));
108
109 // Filter tab
110
111 QLabel * pLabel = new QLabel(__tr2qs("Message Types"), m_pOptionsWidget); //groupbox title
112 pOptionsLayout->addWidget(pLabel, 0, 0, 1, 2);
113
114 m_pFilterView = new QTreeWidget(m_pOptionsWidget);
115 m_pFilterView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
116 m_pFilterView->setRootIsDecorated(false);
117 //FIXME hardcoded size sucks
118 m_pFilterView->setMinimumSize(QSize(200, 150));
119 m_pFilterView->setColumnCount(1);
120 m_pFilterView->header()->hide();
121 pOptionsLayout->addWidget(m_pFilterView, 1, 0, 4, 2);
122
123 m_pFilterItems = (KviIrcMessageCheckListItem **)KviMemory::allocate(KVI_NUM_MSGTYPE_OPTIONS * sizeof(KviIrcMessageCheckListItem *));
124
125 for(int i = 0; i < KVI_NUM_MSGTYPE_OPTIONS; i++)
126 {
127 m_pFilterItems[i] = new KviIrcMessageCheckListItem(m_pFilterView, this, i);
128 }
129
130 pButton = new QPushButton(__tr2qs("Set &All"), m_pOptionsWidget);
131 connect(pButton, SIGNAL(clicked()), this, SLOT(filterEnableAll()));
132 pOptionsLayout->addWidget(pButton, 6, 0);
133
134 pButton = new QPushButton(__tr2qs("Set &None"), m_pOptionsWidget);
135 connect(pButton, SIGNAL(clicked()), this, SLOT(filterEnableNone()));
136 pOptionsLayout->addWidget(pButton, 6, 1);
137
138 pButton = new QPushButton(__tr2qs("&Load from..."), m_pOptionsWidget);
139 connect(pButton, SIGNAL(clicked()), this, SLOT(filterLoad()));
140 pOptionsLayout->addWidget(pButton, 7, 0);
141
142 pButton = new QPushButton(__tr2qs("&Save As..."), m_pOptionsWidget);
143 connect(pButton, SIGNAL(clicked()), this, SLOT(filterSave()));
144 pOptionsLayout->addWidget(pButton, 7, 1);
145
146 pLabel = new QLabel(__tr2qs("Pattern:"), m_pOptionsWidget);
147 pOptionsLayout->addWidget(pLabel, 8, 0);
148 m_pSearchMode = new QComboBox(m_pOptionsWidget);
149 m_pSearchMode->insertItem(PlainText, __tr2qs("Plain Text"));
150 m_pSearchMode->insertItem(Wildcards, __tr2qs("Wildcards"));
151 m_pSearchMode->insertItem(RegExp, __tr2qs("RegExp"));
152 pOptionsLayout->addWidget(m_pSearchMode, 8, 1);
153
154 pLabel = new QLabel(__tr2qs("Match:"), m_pOptionsWidget);
155 pOptionsLayout->addWidget(pLabel, 9, 0);
156
157 m_pCaseSensitive = new QCheckBox(__tr2qs("&Case sensitive"), m_pOptionsWidget);
158 pOptionsLayout->addWidget(m_pCaseSensitive, 9, 1);
159
160 // Focusing the 'string to find' widget has been moved to the toggle function so that it happens whenever the widget is shown
161
162 KviShortcut::create(Qt::Key_Escape, m_pIrcView, SLOT(toggleToolWidget()), nullptr, Qt::WidgetWithChildrenShortcut);
163 KviShortcut::create(KVI_SHORTCUTS_WIN_SEARCH, m_pIrcView, SLOT(toggleToolWidget()), nullptr, Qt::WidgetWithChildrenShortcut);
164 }
165
~KviIrcViewToolWidget()166 KviIrcViewToolWidget::~KviIrcViewToolWidget()
167 {
168 if(m_pIrcView)
169 if(m_pIrcView->parentKviWindow())
170 if(m_pIrcView->parentKviWindow()->input())
171 m_pIrcView->parentKviWindow()->input()->setFocus();
172 }
173
toggleOptions()174 void KviIrcViewToolWidget::toggleOptions()
175 {
176 if(m_pOptionsWidget->isVisible())
177 {
178 m_pOptionsWidget->hide();
179 }
180 else
181 {
182 m_pOptionsWidget->adjustSize();
183 QPoint p = QPoint(
184 m_pOptionsButton->pos().x() + m_pOptionsButton->width() - m_pOptionsWidget->width(),
185 m_pOptionsButton->pos().y() - m_pOptionsWidget->height());
186 m_pOptionsWidget->popup(mapToGlobal(p));
187 }
188 }
189
filterEnableAll()190 void KviIrcViewToolWidget::filterEnableAll()
191 {
192 for(int i = 0; i < KVI_NUM_MSGTYPE_OPTIONS; i++)
193 m_pFilterItems[i]->setOn(true);
194 }
195
filterEnableNone()196 void KviIrcViewToolWidget::filterEnableNone()
197 {
198 for(int i = 0; i < KVI_NUM_MSGTYPE_OPTIONS; i++)
199 m_pFilterItems[i]->setOn(false);
200 }
201
filterLoad()202 void KviIrcViewToolWidget::filterLoad()
203 {
204 QString szFile;
205 QString szInit;
206 g_pApp->getLocalKvircDirectory(szInit, KviApplication::Filters);
207
208 if(KviFileDialog::askForOpenFileName(szFile, __tr2qs("Select a File - KVIrc"), szInit, QString(), false, true, this)) // This is the window title
209 {
210 QFile f(szFile);
211 if(f.open(QIODevice::ReadOnly))
212 {
213 char cBuffer[KVI_NUM_MSGTYPE_OPTIONS];
214 KviMemory::set(cBuffer, 0, KVI_NUM_MSGTYPE_OPTIONS);
215 f.read(cBuffer, KVI_NUM_MSGTYPE_OPTIONS);
216 f.close();
217 for(int i = 0; i < KVI_NUM_MSGTYPE_OPTIONS; i++)
218 {
219 m_pFilterItems[i]->setOn(cBuffer[i]);
220 }
221 forceRepaint();
222 }
223 else
224 {
225 KviMessageBox::warning(__tr2qs("Can't open the filter file %s for reading."), &szFile);
226 }
227 }
228 }
229
filterSave()230 void KviIrcViewToolWidget::filterSave()
231 {
232 QString szFile;
233 QString szInit;
234 g_pApp->getLocalKvircDirectory(szInit, KviApplication::Filters, "filter.kvf");
235 if(KviFileDialog::askForSaveFileName(szFile, __tr2qs("Enter a Filename - KVIrc"), szInit, QString(), false, false, true, this)) // this is the window title
236 {
237 QFile f(szFile);
238 if(f.open(QIODevice::WriteOnly))
239 {
240 char cBuffer[KVI_NUM_MSGTYPE_OPTIONS];
241 for(int i = 0; i < KVI_NUM_MSGTYPE_OPTIONS; i++)
242 {
243 cBuffer[i] = messageEnabled(i) ? 1 : 0;
244 }
245 if(f.write(cBuffer, KVI_NUM_MSGTYPE_OPTIONS) < KVI_NUM_MSGTYPE_OPTIONS)
246 KviMessageBox::warning(__tr2qs("Failed to write the filter file %Q (IO Error)"), &szFile);
247 f.close();
248 }
249 else
250 KviMessageBox::warning(__tr2qs("Can't open the filter file %Q for writing"), &szFile);
251 }
252 }
253
focusStringToFind()254 void KviIrcViewToolWidget::focusStringToFind()
255 {
256 #ifndef COMPILE_ON_MAC
257 m_pStringToFind->setFocus(); // this makes MacOSX version of Qt go nuts and crash
258 #endif //!COMPILE_ON_MAC
259 }
260
forceRepaint()261 void KviIrcViewToolWidget::forceRepaint()
262 {
263 #if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW)
264 m_pIrcView->repaint();
265 #else
266 m_pIrcView->paintEvent(nullptr);
267 #endif
268 }
269
setFindResult(const QString &)270 void KviIrcViewToolWidget::setFindResult(const QString &)
271 {
272 // m_pFindResult->setText(szText);
273 }
274
findPrev()275 void KviIrcViewToolWidget::findPrev()
276 {
277 SearchMode eMode = (SearchMode)m_pSearchMode->currentIndex();
278 m_pIrcView->findPrev(m_pStringToFind->text(), m_pCaseSensitive->isChecked(), eMode != PlainText, eMode == RegExp);
279 }
280
findNextHelper(QString)281 void KviIrcViewToolWidget::findNextHelper(QString)
282 {
283 m_pIrcView->m_pCursorLine = m_pIrcView->m_pFirstLine;
284 findNext();
285 }
286
findNext()287 void KviIrcViewToolWidget::findNext()
288 {
289 SearchMode eMode = (SearchMode)m_pSearchMode->currentIndex();
290 m_pIrcView->findNext(m_pStringToFind->text(), m_pCaseSensitive->isChecked(), eMode != PlainText, eMode == RegExp);
291 }
292
293 //
294 // Link tip label implementation
295 //
296
KviIrcViewToolTip(KviIrcView * pView)297 KviIrcViewToolTip::KviIrcViewToolTip(KviIrcView * pView)
298 : KviTalToolTip(pView)
299 {
300 m_pView = pView;
301 }
302
303 KviIrcViewToolTip::~KviIrcViewToolTip()
304 = default;
305
maybeTip(const QPoint & pnt)306 void KviIrcViewToolTip::maybeTip(const QPoint & pnt)
307 {
308 m_pView->maybeTip(pnt);
309 }
310