1 /*  smplayer, GUI front-end for mplayer.
2     Copyright (C) 2006-2021 Ricardo Villalba <ricardo@smplayer.info>
3 
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8 
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13 
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17 */
18 
19 #include "favoriteeditor.h"
20 #include "images.h"
21 
22 #include <QHeaderView>
23 #include <QFileDialog>
24 #include <QItemDelegate>
25 #include "filechooser.h"
26 
27 #if QT_VERSION >= 0x050000
28 #include "myscroller.h"
29 #endif
30 
31 #define COL_ICON 0
32 #define COL_NAME 1
33 #define COL_FILE 2
34 
35 
36 class FEDelegate : public QItemDelegate
37 {
38 public:
39 	FEDelegate(QObject *parent = 0);
40 
41 	QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
42                            const QModelIndex &index) const;
43 	virtual void setModelData(QWidget * editor, QAbstractItemModel * model,
44                               const QModelIndex & index ) const;
45 };
46 
FEDelegate(QObject * parent)47 FEDelegate::FEDelegate(QObject *parent) : QItemDelegate(parent) {
48 }
49 
createEditor(QWidget * parent,const QStyleOptionViewItem & option,const QModelIndex & index) const50 QWidget * FEDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem & option, const QModelIndex & index) const {
51 	//qDebug("FEDelegate::createEditor");
52 
53 	if (index.column() == COL_FILE) {
54 		FileChooser * fch = new FileChooser(parent);
55 		fch->setOptions(QFileDialog::DontUseNativeDialog | QFileDialog::DontResolveSymlinks); // Crashes if the native dialog is used
56 		fch->setText( index.model()->data(index, Qt::DisplayRole).toString() );
57 		return fch;
58 	}
59 	else
60 	if (index.column() == COL_NAME) {
61 		QLineEdit * e = new QLineEdit(parent);
62 		e->setText( index.model()->data(index, Qt::DisplayRole).toString() );
63 		return e;
64 	}
65 	else {
66 		return QItemDelegate::createEditor(parent, option, index);
67 	}
68 }
69 
setModelData(QWidget * editor,QAbstractItemModel * model,const QModelIndex & index) const70 void FEDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const {
71 	if (index.column() == COL_FILE) {
72 		FileChooser * fch = static_cast<FileChooser*>(editor);
73 		model->setData(index, fch->text() );
74 	}
75 	else
76 	if (index.column() == COL_NAME) {
77 		QLineEdit * e = static_cast<QLineEdit*>(editor);
78 		model->setData(index, e->text() );
79 	}
80 }
81 
82 QString FavoriteEditor::last_dir;
83 
FavoriteEditor(QWidget * parent,Qt::WindowFlags f)84 FavoriteEditor::FavoriteEditor( QWidget* parent, Qt::WindowFlags f )
85 	: QDialog(parent, f)
86 {
87 	setupUi(this);
88 
89 	add_button->setIcon( Images::icon("favorite-add") );
90 	add_submenu_button->setIcon( Images::icon("favorite-folder") );
91 	delete_button->setIcon( Images::icon("delete") );
92 	delete_all_button->setIcon( Images::icon("trash") );
93 	up_button->setIcon( Images::icon("up") );
94 	down_button->setIcon( Images::icon("down") );
95 
96 	table->setColumnCount(3);
97 	table->setHorizontalHeaderLabels(QStringList() << tr("Icon") << tr("Name") << tr("Media") );
98 
99 	table->setAlternatingRowColors(true);
100 #if QT_VERSION >= 0x050000
101 	MyScroller::setScroller(table->viewport());
102 
103 	table->horizontalHeader()->setSectionResizeMode(COL_FILE, QHeaderView::Stretch);
104 #else
105 	table->horizontalHeader()->setResizeMode(COL_FILE, QHeaderView::Stretch);
106 #endif
107 
108 	table->setSelectionBehavior(QAbstractItemView::SelectRows);
109 	table->setSelectionMode(QAbstractItemView::SingleSelection);
110 
111 	table->setItemDelegateForColumn( COL_NAME, new FEDelegate(table) );
112 	table->setItemDelegateForColumn( COL_FILE, new FEDelegate(table) );
113 
114 	connect(table, SIGNAL(cellActivated(int,int)), this, SLOT(edit_icon(int,int)));
115 
116 	setWindowTitle( tr("Favorite editor") );
117 
118 	setCaption( tr("Favorite list") );
119 	setIntro( tr("You can edit, delete, sort or add new items. Double click on "
120                  "a cell to edit its contents.") );
121 
122 	setDialogIcon( Images::icon("favorite", 64) );
123 }
124 
~FavoriteEditor()125 FavoriteEditor::~FavoriteEditor() {
126 }
127 
setCaption(const QString & caption)128 void FavoriteEditor::setCaption(const QString & caption) {
129 	caption_text = caption;
130 	updateTitleLabel();
131 }
132 
caption()133 QString FavoriteEditor::caption() {
134 	return caption_text;
135 }
136 
setIntro(const QString & intro)137 void FavoriteEditor::setIntro(const QString & intro) {
138 	intro_text = intro;
139 	updateTitleLabel();
140 }
141 
intro()142 QString FavoriteEditor::intro() {
143 	return intro_text;
144 }
145 
updateTitleLabel()146 void FavoriteEditor::updateTitleLabel() {
147 	title_label->setText( "<h1>" + caption_text + "</h1>" + intro_text );
148 }
149 
setDialogIcon(const QPixmap & icon)150 void FavoriteEditor::setDialogIcon( const QPixmap & icon ) {
151 	dialog_icon->setPixmap(icon);
152 }
153 
dialogIcon() const154 QPixmap FavoriteEditor::dialogIcon() const {
155 #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
156 	return dialog_icon->pixmap(Qt::ReturnByValue);
157 #else
158 	return QPixmap(*dialog_icon->pixmap());
159 #endif
160 }
161 
setData(FavoriteList list)162 void FavoriteEditor::setData( FavoriteList list ) {
163 	table->setRowCount(list.count());
164 
165 	for (int n = 0; n < list.count(); n++) {
166 		QTableWidgetItem * icon_item = new QTableWidgetItem;
167 		icon_item->setIcon( QIcon(list[n].icon()) );
168 		icon_item->setData( Qt::UserRole, list[n].icon() );
169 		icon_item->setData( Qt::ToolTipRole, list[n].icon() );
170 		icon_item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
171 
172 		QTableWidgetItem * name_item = new QTableWidgetItem;
173 		name_item->setText( list[n].name() );
174 
175 		QTableWidgetItem * file_item = new QTableWidgetItem;
176 		file_item->setData( Qt::ToolTipRole, list[n].file() );
177 		file_item->setData( Qt::UserRole, list[n].isSubentry() );
178 		if (list[n].isSubentry()) {
179 			file_item->setFlags(Qt::ItemIsSelectable);
180 			file_item->setData( Qt::UserRole + 1, list[n].file() );
181 			file_item->setText( tr("Favorite list") );
182 		} else {
183 			file_item->setText( list[n].file() );
184 		}
185 
186 		table->setItem(n, COL_ICON, icon_item);
187 		table->setItem(n, COL_NAME, name_item);
188 		table->setItem(n, COL_FILE, file_item);
189 	}
190 
191 	//table->resizeColumnsToContents();
192 
193 	//table->setCurrentCell(0, 0);
194 	table->setCurrentCell(table->rowCount()-1, 0);
195 }
196 
data()197 FavoriteList FavoriteEditor::data() {
198 	FavoriteList list;
199 
200 	for (int n = 0; n < table->rowCount(); n++) {
201 		Favorite f;
202 		f.setName( table->item(n, COL_NAME)->text() );
203 		f.setIcon( table->item(n, COL_ICON)->data(Qt::UserRole).toString() );
204 		f.setSubentry( table->item(n, COL_FILE)->data(Qt::UserRole).toBool() );
205 		if (f.isSubentry()) {
206 			f.setFile( table->item(n, COL_FILE)->data(Qt::UserRole + 1).toString() );
207 		} else {
208 			f.setFile( table->item(n, COL_FILE)->text() );
209 		}
210 
211 		list.append(f);
212 	}
213 
214 	return list;
215 }
216 
on_delete_button_clicked()217 void FavoriteEditor::on_delete_button_clicked() {
218 	int row = table->currentRow();
219 	qDebug("FavoriteEditor::on_delete_button_clicked: current_row: %d", row);
220 
221 	if (row > -1) table->removeRow(row);
222 
223 	if (row >= table->rowCount()) row--;
224 	table->setCurrentCell(row, table->currentColumn());
225 }
226 
on_delete_all_button_clicked()227 void FavoriteEditor::on_delete_all_button_clicked() {
228 	qDebug("FavoriteEditor::on_delete_all_button_clicked");
229 	table->setRowCount(0);
230 }
231 
on_add_button_clicked()232 void FavoriteEditor::on_add_button_clicked() {
233 	int row = table->currentRow();
234 	qDebug("FavoriteEditor::on_add_button_clicked: current_row: %d", row);
235 	row++;
236 	table->insertRow(row);
237 
238 	QTableWidgetItem * icon_item = new QTableWidgetItem;
239 	icon_item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
240 
241 	table->setItem(row, COL_ICON, icon_item);
242 	table->setItem(row, COL_NAME, new QTableWidgetItem);
243 	table->setItem(row, COL_FILE, new QTableWidgetItem);
244 
245 	table->setCurrentCell(row, table->currentColumn());
246 }
247 
on_add_submenu_button_clicked()248 void FavoriteEditor::on_add_submenu_button_clicked() {
249 	qDebug("FavoriteEditor::on_add_submenu_button_clicked");
250 	qDebug("FavoriteEditor::on_add_submenu_button_clicked: store_path: '%s'", store_path.toUtf8().constData());
251 
252 	QString filename;
253 	//QString s;
254 	int n = 1;
255 	do {
256 		filename = QString("favorites%1.m3u8").arg(n, 4, 10, QChar('0'));
257 		if (!store_path.isEmpty()) filename = store_path +"/"+ filename;
258 		qDebug("FavoriteEditor::on_add_submenu_button_clicked: filename: '%s'", filename.toUtf8().constData());
259 		n++;
260 	} while (QFile::exists(filename));
261 
262 	qDebug("FavoriteEditor::on_add_submenu_button_clicked: chosen filename: '%s'", filename.toUtf8().constData());
263 
264 
265 	int row = table->currentRow();
266 	row++;
267 	table->insertRow(row);
268 
269 	QTableWidgetItem * icon_item = new QTableWidgetItem;
270 	icon_item->setData( Qt::UserRole, Images::file("openfolder") );
271 	icon_item->setIcon( Images::icon("openfolder") );
272 	icon_item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
273 
274 	table->setItem(row, COL_ICON, icon_item);
275 	table->setItem(row, COL_NAME, new QTableWidgetItem);
276 
277 	QTableWidgetItem * file_item = new QTableWidgetItem;
278 	file_item->setData( Qt::UserRole, true );
279 	file_item->setFlags(Qt::ItemIsSelectable);
280 	file_item->setData( Qt::UserRole + 1, filename );
281 	file_item->setText( tr("Favorite list") );
282 	file_item->setData( Qt::ToolTipRole, filename );
283 	table->setItem(row, COL_FILE, file_item);
284 
285 	table->setCurrentCell(row, table->currentColumn());
286 }
287 
on_up_button_clicked()288 void FavoriteEditor::on_up_button_clicked() {
289 	int row = table->currentRow();
290 	qDebug("FavoriteEditor::on_up_button_clicked: current_row: %d", row);
291 
292 	if (row == 0) return;
293 
294 	// take whole rows
295 	QList<QTableWidgetItem*> source_items = takeRow(row);
296 	QList<QTableWidgetItem*> dest_items = takeRow(row-1);
297 
298 	// set back in reverse order
299 	setRow(row, dest_items);
300 	setRow(row-1, source_items);
301 
302 	table->setCurrentCell(row-1, table->currentColumn());
303 }
304 
on_down_button_clicked()305 void FavoriteEditor::on_down_button_clicked() {
306 	int row = table->currentRow();
307 	qDebug("FavoriteEditor::on_down_button_clicked: current_row: %d", row);
308 
309 	if ((row+1) >= table->rowCount()) return;
310 
311 	// take whole rows
312 	QList<QTableWidgetItem*> source_items = takeRow(row);
313 	QList<QTableWidgetItem*> dest_items = takeRow(row+1);
314 
315 	// set back in reverse order
316 	setRow(row, dest_items);
317 	setRow(row+1, source_items);
318 
319 	table->setCurrentCell(row+1, table->currentColumn());
320 }
321 
322 // takes and returns the whole row
takeRow(int row)323 QList<QTableWidgetItem*> FavoriteEditor::takeRow(int row) {
324 	QList<QTableWidgetItem*> rowItems;
325 	for (int col = 0; col < table->columnCount(); ++col)
326 	{
327 		rowItems << table->takeItem(row, col);
328 	}
329 	return rowItems;
330 }
331 
332 // sets the whole row
setRow(int row,const QList<QTableWidgetItem * > & rowItems)333 void FavoriteEditor::setRow(int row, const QList<QTableWidgetItem*>& rowItems)
334 {
335 	for (int col = 0; col < table->columnCount(); ++col)
336 	{
337 		table->setItem(row, col, rowItems.at(col));
338 	}
339 }
340 
edit_icon(int row,int column)341 void FavoriteEditor::edit_icon(int row, int column ) {
342 	qDebug("FavoriteEditor::edit_icon: %d, %d", row, column);
343 
344 	if (column != COL_ICON) return;
345 
346 	QTableWidgetItem * i = table->item(row, column);
347 	QString icon_filename = i->data(Qt::UserRole).toString();
348 
349 	qDebug("FavoriteEditor::edit_icon: icon file: '%s'", icon_filename.toUtf8().constData());
350 
351 	QString dir = icon_filename;
352 	if (dir.isEmpty()) dir = last_dir;
353 
354 	QString res = QFileDialog::getOpenFileName(this, tr("Select an icon file"),
355                                                dir,
356                                                tr("Images") + " (*.png *.xpm *.jpg)");
357 	if (!res.isEmpty()) {
358 		i->setIcon( QIcon(res) );
359 		i->setData( Qt::UserRole, res );
360 
361 		last_dir = QFileInfo(res).absolutePath();
362 	}
363 }
364 
365 #include "moc_favoriteeditor.cpp"
366