1 //=============================================================================
2 //
3 //   File : OptionsWidget_textIcons.cpp
4 //   Creation date : Fri May 24 2002 00:16:13 CEST by Szymon Stefanek
5 //
6 //   This file is part of the KVIrc IRC client distribution
7 //   Copyright (C) 2002-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 "OptionsWidget_textIcons.h"
26 
27 #include "KviIconManager.h"
28 
29 #include "KviApplication.h"
30 #include "KviOptions.h"
31 #include "KviTextIconManager.h"
32 #include "KviLocale.h"
33 #include "KviFileDialog.h"
34 #include "kvi_fileextensions.h"
35 #include "KviTalHBox.h"
36 #include "KviFileUtils.h"
37 
38 #include <QToolButton>
39 #include <QLayout>
40 #include <QCursor>
41 #include <QHeaderView>
42 #include <QWidgetAction>
43 #include <QMenu>
44 
TextIconTableItem(QTableWidget *,KviTextIcon * icon)45 TextIconTableItem::TextIconTableItem(QTableWidget *, KviTextIcon * icon)
46     : QTableWidgetItem(QString(), Qt::ItemIsEditable)
47 {
48 	if(icon)
49 		m_pIcon = icon;
50 	else
51 		m_pIcon = new KviTextIcon(KviIconManager::None);
52 	QPixmap * pix = m_pIcon->pixmap();
53 	if(pix)
54 		setIcon(QIcon(*pix));
55 }
56 
~TextIconTableItem()57 TextIconTableItem::~TextIconTableItem()
58 {
59 	delete m_pIcon;
60 }
61 
setId(int id)62 void TextIconTableItem::setId(int id)
63 {
64 	m_pIcon->setId(id);
65 	QPixmap * pix = m_pIcon->pixmap();
66 	if(pix)
67 		setIcon(QIcon(*pix));
68 }
69 
OptionsWidget_textIcons(QWidget * parent)70 OptionsWidget_textIcons::OptionsWidget_textIcons(QWidget * parent)
71     : KviOptionsWidget(parent)
72 {
73 	m_pPopup = nullptr;
74 	m_iLastEditedRow = -1;
75 	m_pCurrentIconButton = nullptr;
76 	setObjectName("texticons_options_widget");
77 	createLayout();
78 
79 	m_pTable = new QTableWidget(this);
80 
81 	m_pTable->setColumnCount(2);
82 	m_pTable->setColumnWidth(0, 300);
83 	m_pTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
84 	m_pTable->horizontalHeader()->stretchLastSection();
85 	m_pTable->setSelectionBehavior(QAbstractItemView::SelectRows);
86 	m_pTable->setSelectionMode(QAbstractItemView::SingleSelection);
87 	m_pTable->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
88 
89 	mergeTip(m_pTable->viewport(), __tr2qs_ctx("This table contains the text icon associations.<br>"
90 	                                           "KVIrc will use them to display the Alt+E escape sequences "
91 	                                           "and eventually the emoticons.", "options"));
92 
93 	layout()->addWidget(m_pTable, 0, 0, 1, 3);
94 
95 	m_pAdd = new QPushButton(__tr2qs_ctx("Add", "options"), this);
96 	layout()->addWidget(m_pAdd, 1, 0);
97 	connect(m_pAdd, SIGNAL(clicked()), this, SLOT(addClicked()));
98 
99 	m_pDel = new QPushButton(__tr2qs_ctx("Delete", "options"), this);
100 	layout()->addWidget(m_pDel, 1, 1);
101 	connect(m_pDel, SIGNAL(clicked()), this, SLOT(delClicked()));
102 
103 	m_pRestore = new QPushButton(__tr2qs_ctx("Restore", "options"), this);
104 	layout()->addWidget(m_pRestore, 1, 2);
105 	connect(m_pRestore, SIGNAL(clicked()), this, SLOT(restoreClicked()));
106 
107 	connect(m_pTable, SIGNAL(itemSelectionChanged()), this, SLOT(itemSelectionChanged()));
108 	connect(m_pTable, SIGNAL(currentItemChanged(QTableWidgetItem *, QTableWidgetItem *)), this, SLOT(currentItemChanged(QTableWidgetItem *, QTableWidgetItem *)));
109 
110 	fillTable();
111 }
112 
113 OptionsWidget_textIcons::~OptionsWidget_textIcons()
114     = default;
115 
fillTable()116 void OptionsWidget_textIcons::fillTable()
117 {
118 	KviPointerHashTableIterator<QString, KviTextIcon> it(*(g_pTextIconManager->textIconDict()));
119 
120 	m_pTable->clear();
121 	QStringList header;
122 	header.append(__tr2qs("Text"));
123 	header.append(__tr2qs("Emoticon"));
124 	m_pTable->setHorizontalHeaderLabels(header);
125 	m_pTable->setRowCount(g_pTextIconManager->textIconDict()->count());
126 
127 	int idx = 0;
128 	QTableWidgetItem * item0;
129 	TextIconTableItem * item1;
130 	while(KviTextIcon * i = it.current())
131 	{
132 		if(!m_pTable->item(idx, 0))
133 		{
134 			item0 = new QTableWidgetItem(it.currentKey());
135 			m_pTable->setItem(idx, 0, item0);
136 		}
137 
138 		item1 = new TextIconTableItem(m_pTable, new KviTextIcon(i));
139 		//remove from the item the ability to be edited as text
140 		item1->setFlags(item1->flags() ^ Qt::ItemIsEditable);
141 		m_pTable->setItem(idx, 1, item1);
142 
143 		++idx;
144 		++it;
145 	}
146 
147 	// disable the delete button
148 	m_pDel->setEnabled(false);
149 }
150 
doPopup()151 void OptionsWidget_textIcons::doPopup()
152 {
153 	if(!m_pPopup)
154 	{
155 		m_pPopup = new QMenu(this);
156 		KviIconWidget * iw = new KviIconWidget(m_pPopup);
157 		connect(iw, SIGNAL(selected(KviIconManager::SmallIcon)), this, SLOT(iconSelected(KviIconManager::SmallIcon)));
158 		QWidgetAction * pWaction = new QWidgetAction(m_pPopup);
159 		pWaction->setDefaultWidget(iw);
160 		m_pPopup->addAction(pWaction);
161 	}
162 	m_pPopup->popup(QCursor::pos());
163 }
164 
iconSelected(KviIconManager::SmallIcon eIcon)165 void OptionsWidget_textIcons::iconSelected(KviIconManager::SmallIcon eIcon)
166 {
167 	m_pCurrentItem->icon()->setId(eIcon);
168 	m_pCurrentItem->setIcon(QIcon(*m_pCurrentItem->icon()->pixmap()));
169 
170 	KviTalHBox * pBox = new KviTalHBox(nullptr);
171 	pBox->setSpacing(0);
172 	pBox->setMargin(0);
173 
174 	m_pCurrentIconButton = new QToolButton(pBox);
175 	m_pCurrentIconButton->setMinimumWidth(90);
176 	m_pCurrentIconButton->setIcon(QIcon(*m_pCurrentItem->icon()->pixmap()));
177 
178 	connect(m_pCurrentIconButton, SIGNAL(clicked()), this, SLOT(doPopup()));
179 
180 	QToolButton * pBrowseButton = new QToolButton(pBox);
181 	pBrowseButton->setText(__tr2qs("&Browse..."));
182 	connect(pBrowseButton, SIGNAL(clicked()), this, SLOT(chooseFromFile()));
183 
184 	m_pTable->setCellWidget(m_pCurrentItem->row(), 1, pBox);
185 }
186 
chooseFromFile()187 void OptionsWidget_textIcons::chooseFromFile()
188 {
189 	QString szFile;
190 	KviFileDialog::askForOpenFileName(szFile, __tr2qs_ctx("Select a File - KVIrc", "options"), QString(), KVI_FILTER_IMAGE, false, true, this);
191 	if(szFile.isEmpty())
192 		return;
193 
194 	if(!g_pIconManager->getPixmap(szFile))
195 		return;
196 
197 	QFileInfo info(szFile);
198 
199 	QString szFileName = info.fileName();
200 
201 	QString szCurrentThemePath;
202 	g_pApp->getLocalKvircDirectory(szCurrentThemePath, KviApplication::Themes, KVI_OPTION_STRING(KviOption_stringIconThemeSubdir));
203 
204 	szCurrentThemePath += KVI_PATH_SEPARATOR_CHAR;
205 
206 	if(!KviFileUtils::directoryExists(szCurrentThemePath))
207 		KviFileUtils::makeDir(szCurrentThemePath);
208 
209 	KviFileUtils::copyFile(szFile, szCurrentThemePath + szFileName);
210 
211 	m_pCurrentItem->icon()->setFilename(szFileName);
212 
213 	QPixmap * p = m_pCurrentItem->icon()->pixmap();
214 	m_pCurrentItem->setIcon(QIcon(*p));
215 
216 	if(m_pCurrentIconButton)
217 		m_pCurrentIconButton->setIcon(QIcon(*p));
218 }
219 
itemSelectionChanged()220 void OptionsWidget_textIcons::itemSelectionChanged()
221 {
222 	int i = m_pTable->currentRow();
223 	m_pDel->setEnabled(i >= 0 && i < m_pTable->rowCount());
224 }
225 
currentItemChanged(QTableWidgetItem * cur,QTableWidgetItem * prev)226 void OptionsWidget_textIcons::currentItemChanged(QTableWidgetItem * cur, QTableWidgetItem * prev)
227 {
228 	if(prev)
229 	{
230 		QWidget * pOldWidget = m_pTable->cellWidget(prev->row(), 1);
231 		if(pOldWidget)
232 			m_pTable->setCellWidget(prev->row(), 1, nullptr);
233 	}
234 
235 	m_pCurrentItem = nullptr;
236 
237 	if(!cur)
238 		return;
239 	if(cur->column() != 1)
240 		return;
241 	if(m_iLastEditedRow == cur->row() || cur == prev)
242 		return;
243 
244 	m_pCurrentItem = (TextIconTableItem *)cur;
245 
246 	KviTalHBox * pBox = new KviTalHBox(nullptr);
247 	pBox->setSpacing(0);
248 	pBox->setMargin(0);
249 
250 	m_pCurrentIconButton = new QToolButton(pBox);
251 	m_pCurrentIconButton->setMinimumWidth(90);
252 	m_pCurrentIconButton->setIcon(QIcon(cur->icon()));
253 	m_pCurrentIconButton->setText(__tr2qs("&Select..."));
254 	connect(m_pCurrentIconButton, SIGNAL(clicked()), this, SLOT(doPopup()));
255 
256 	QToolButton * pBrowseButton = new QToolButton(pBox);
257 	pBrowseButton->setText(__tr2qs("&Browse..."));
258 	connect(pBrowseButton, SIGNAL(clicked()), this, SLOT(chooseFromFile()));
259 
260 	m_pTable->setCellWidget(cur->row(), 1, pBox);
261 	m_iLastEditedRow = cur->row();
262 }
263 
addClicked()264 void OptionsWidget_textIcons::addClicked()
265 {
266 	m_pTable->setRowCount(m_pTable->rowCount() + 1);
267 	m_pTable->setItem(m_pTable->rowCount() - 1, 0, new QTableWidgetItem(__tr2qs_ctx("unnamed", "options")));
268 	m_pTable->setItem(m_pTable->rowCount() - 1, 1, new TextIconTableItem(m_pTable, nullptr));
269 	m_pTable->scrollToBottom();
270 	m_pDel->setEnabled(true);
271 }
272 
restoreClicked()273 void OptionsWidget_textIcons::restoreClicked()
274 {
275 	g_pTextIconManager->checkDefaultAssociations();
276 	fillTable();
277 }
278 
delClicked()279 void OptionsWidget_textIcons::delClicked()
280 {
281 	int i = m_pTable->currentRow();
282 
283 	if((i > -1) && (i < m_pTable->rowCount()))
284 	{
285 		m_pTable->removeRow(i);
286 		if(m_pTable->rowCount() == 0)
287 			m_pDel->setEnabled(false);
288 	}
289 }
290 
commit()291 void OptionsWidget_textIcons::commit()
292 {
293 	KviOptionsWidget::commit();
294 	g_pTextIconManager->clear();
295 	int n = m_pTable->rowCount();
296 	for(int i = 0; i < n; i++)
297 	{
298 		QString szVal = m_pTable->item(i, 0)->text();
299 		if(!szVal.isEmpty())
300 		{
301 			TextIconTableItem * it = (TextIconTableItem *)m_pTable->item(i, 1);
302 			if(it)
303 			{
304 				g_pTextIconManager->insert(szVal, *(it->icon()));
305 			}
306 		}
307 	}
308 	g_pTextIconManager->save();
309 
310 	for(int i = 0; i < n; i++)
311 	{
312 		for(int j = 0; j < m_pTable->columnCount(); j++)
313 		{
314 			if(m_pTable->item(i, j))
315 				m_pTable->takeItem(i, j);
316 		}
317 	}
318 }
319