commandstable.cpp 10.7 KB
Newer Older
Urs Fleisch's avatar
Urs Fleisch committed
1
2
3
4
5
6
7
/**
 * \file commandstable.cpp
 * Context menu commands configuration table.
 *
 * \b Project: Kid3
 * \author Urs Fleisch
 * \date 10 Oct 2005
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 *
 * Copyright (C) 2005-2007  Urs Fleisch
 *
 * This file is part of Kid3.
 *
 * Kid3 is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * Kid3 is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
Urs Fleisch's avatar
Urs Fleisch committed
25
26
27
 */

#include "commandstable.h"
28
29
#include "filelist.h"
#include <qtooltip.h>
Urs Fleisch's avatar
Urs Fleisch committed
30

Urs Fleisch's avatar
Urs Fleisch committed
31
#if QT_VERSION >= 0x040000
32
33
#include <QMenu>
#include <QHeaderView>
Urs Fleisch's avatar
Urs Fleisch committed
34
#else 
Urs Fleisch's avatar
Urs Fleisch committed
35
#include <qpopupmenu.h>
Urs Fleisch's avatar
Urs Fleisch committed
36
#endif
Urs Fleisch's avatar
Urs Fleisch committed
37

Urs Fleisch's avatar
Urs Fleisch committed
38
39
40
41
42
43
44
45
46
/** Column indices. */
enum ColumnIndex {
	CI_Confirm,
	CI_Output,
	CI_Name,
	CI_Command,
	CI_NumColumns
};

Urs Fleisch's avatar
Urs Fleisch committed
47
48
49
50
51
/**
 * Constructor.
 *
 * @param parent parent widget
 */
52
53
54
55
56
57
58
59
60
61
62
#if QT_VERSION >= 0x040000
CommandsTable::CommandsTable(QWidget* parent) :
	QTableWidget(parent)
{
	setColumnCount(CI_NumColumns);
	setHorizontalHeaderLabels(
		QStringList() << i18n("Confirm") << i18n("Output") << i18n("Name") <<
		i18n("Command"));
	resizeColumnToContents(CI_Confirm);
	resizeColumnToContents(CI_Output);
	horizontalHeader()->setResizeMode(CI_Command, QHeaderView::Stretch);
63
	horizontalHeaderItem(CI_Command)->setToolTip(FileList::getFormatToolTip());
64
65
66
67
68
69
70
71
72
73
	setContextMenuPolicy(Qt::CustomContextMenu);
	connect(this, SIGNAL(cellActivated(int, int)),
			this, SLOT(valueChanged(int, int)));
	connect(this, SIGNAL(customContextMenuRequested(const QPoint&)),
			this, SLOT(customContextMenu(const QPoint&)));
}
#else
CommandsTable::CommandsTable(QWidget* parent) :
	QTable(parent)
{
Urs Fleisch's avatar
Urs Fleisch committed
74
75
76
77
78
	setNumCols(CI_NumColumns);
	horizontalHeader()->setLabel(CI_Confirm, i18n("Confirm"));
	horizontalHeader()->setLabel(CI_Output, i18n("Output"));
	horizontalHeader()->setLabel(CI_Name, i18n("Name"));
	horizontalHeader()->setLabel(CI_Command, i18n("Command"));
79
	QToolTip::add(horizontalHeader(), FileList::getFormatToolTip());
Urs Fleisch's avatar
Urs Fleisch committed
80
81
82
	adjustColumn(CI_Confirm);
	adjustColumn(CI_Output);
	setColumnStretchable(CI_Command, true);
Urs Fleisch's avatar
Urs Fleisch committed
83
84
85
86
87
88

	connect(this, SIGNAL(valueChanged(int, int)),
			this, SLOT(valueChanged(int, int)));
	connect(this, SIGNAL(contextMenuRequested(int, int, const QPoint&)),
			this, SLOT(contextMenu(int, int, const QPoint&)));
}
89
#endif
Urs Fleisch's avatar
Urs Fleisch committed
90
91
92
93
94
95
96
97

/**
 * Destructor.
 */
CommandsTable::~CommandsTable() {}

/**
 * Called when a value in the table is changed.
Urs Fleisch's avatar
Urs Fleisch committed
98
 * If the command cell in the last row is changed to a non-empty
Urs Fleisch's avatar
Urs Fleisch committed
99
100
101
102
103
104
 * value, a new row is added. If it is changed to an empty value,
 * the row is deleted.
 *
 * @param row table row of changed item
 * @param col table column of changed item
 */
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#if QT_VERSION >= 0x040000
void CommandsTable::valueChanged(int row, int col)
{
	QTableWidgetItem* twi;
	if (row == rowCount() - 1 && col == CI_Command &&
			(twi = item(row, col)) != 0) {
		if (twi->text().isEmpty()) {
			if (row != 0) {
				deleteRow(row);
			}
		} else {
			addRow(row);
		}
	}
}
#else
Urs Fleisch's avatar
Urs Fleisch committed
121
122
void CommandsTable::valueChanged(int row, int col)
{
Urs Fleisch's avatar
Urs Fleisch committed
123
	if (row == numRows() - 1 && col == CI_Command) {
Urs Fleisch's avatar
Urs Fleisch committed
124
125
126
127
128
		if (text(row, col).isEmpty()) {
			if (row != 0) {
				deleteRow(row);
			}
		} else {
129
			addRow(row);
Urs Fleisch's avatar
Urs Fleisch committed
130
131
132
		}
	}
}
133
#endif
Urs Fleisch's avatar
Urs Fleisch committed
134
135
136
137
138
139

/**
 * Insert a new row into the table.
 *
 * @param row the new row is inserted after this row
 */
140
void CommandsTable::addRow(int row)
Urs Fleisch's avatar
Urs Fleisch committed
141
{
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#if QT_VERSION >= 0x040000
	insertRow(row + 1);

	QTableWidgetItem* twi;
	if ((twi = item(row + 1, CI_Confirm)) == 0) {
		twi = new QTableWidgetItem;
		setItem(row + 1, CI_Confirm, twi);
	}
	twi->setCheckState(Qt::Unchecked);

	if ((twi = item(row + 1, CI_Output)) == 0) {
		twi = new QTableWidgetItem;
		setItem(row + 1, CI_Output, twi);
	}
	twi->setCheckState(Qt::Unchecked);

	if ((twi = item(row + 1, CI_Name)) != 0)
		twi->setText("");
	else
		setItem(row + 1, CI_Name, new QTableWidgetItem(""));

	if ((twi = item(row + 1, CI_Command)) != 0)
		twi->setText("");
	else
		setItem(row + 1, CI_Command, new QTableWidgetItem(""));
#else
Urs Fleisch's avatar
Urs Fleisch committed
168
	insertRows(row + 1);
169
170
171
	setItem(row + 1, CI_Confirm, new QCheckTableItem(this, ""));
	setItem(row + 1, CI_Output, new QCheckTableItem(this, ""));
#endif
Urs Fleisch's avatar
Urs Fleisch committed
172
173
174
175
176
177
178
179
180
}

/**
 * Delete a row from the table.
 *
 * @param row row to delete
 */
void CommandsTable::deleteRow(int row)
{
181
182
183
#if QT_VERSION >= 0x040000
	if (rowCount() <= 1) return;
#endif
Urs Fleisch's avatar
Urs Fleisch committed
184
185
186
187
188
189
190
191
192
193
	removeRow(row);
}

/**
 * Clear a row in the table.
 *
 * @param row row to clear
 */
void CommandsTable::clearRow(int row)
{
194
195
196
197
198
199
200
201
202
203
#if QT_VERSION >= 0x040000
	QTableWidgetItem* twi = item(row, CI_Name);
	if (twi) twi->setText("");
	twi = item(row, CI_Command);
	if (twi) twi->setText("");
	twi = item(row, CI_Confirm);
	if (twi) twi->setCheckState(Qt::Unchecked);
	twi = item(row, CI_Output);
	if (twi) twi->setCheckState(Qt::Unchecked);
#else
Urs Fleisch's avatar
Urs Fleisch committed
204
205
	setText(row, CI_Name, "");
	setText(row, CI_Command, "");
206
207
	QTableItem* ti = item(row, CI_Confirm);
	QCheckTableItem* cti = dynamic_cast<QCheckTableItem*>(ti);
Urs Fleisch's avatar
Urs Fleisch committed
208
209
210
	if (cti) {
		cti->setChecked(false);
	}
Urs Fleisch's avatar
Urs Fleisch committed
211
	ti = item(row, CI_Output);
212
	cti = dynamic_cast<QCheckTableItem*>(ti);
Urs Fleisch's avatar
Urs Fleisch committed
213
214
215
	if (cti) {
		cti->setChecked(false);
	}
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
#endif
}

/**
 * Execute a context menu action.
 *
 * @param action action of selected menu
 */
#if QT_VERSION >= 0x040000
void CommandsTable::executeAction(QAction* action)
{
	if (action) {
		int row = action->data().toInt();
		int cmd = row & 3;
		row >>= 2;
		switch (cmd) {
			case 0:
				addRow(row);
				break;
			case 1:
				deleteRow(row);
				break;
			case 2:
			default:
				clearRow(row);
				break;
		}
	}
Urs Fleisch's avatar
Urs Fleisch committed
244
}
245
246
247
#else
void CommandsTable::executeAction(QAction*) {}
#endif
Urs Fleisch's avatar
Urs Fleisch committed
248
249
250
251
252
253
254
255
256
257

/**
 * Display context menu.
 *
 * @param row row at which context menu is displayed
 * @param col column at which context menu is displayed
 * @param pos position where context menu is drawn on screen
 */
void CommandsTable::contextMenu(int row, int /* col */, const QPoint& pos)
{
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
#if QT_VERSION >= 0x040000
	QMenu menu(this);
	QAction* action;
	if (row >= -1) {
		action = menu.addAction(i18n("&Insert row"));
		if (action) action->setData((row << 2) | 0);
	}
	if (row >= 0) {
		action = menu.addAction(i18n("&Delete row"));
		if (action) action->setData((row << 2) | 1);
	}
	if (row >= 0) {
		action = menu.addAction(i18n("&Clear row"));
		if (action) action->setData((row << 2) | 2);
	}
	connect(&menu, SIGNAL(triggered(QAction*)), this, SLOT(executeAction(QAction*)));
#else
	QPopupMenu menu(this);
Urs Fleisch's avatar
Urs Fleisch committed
276
	if (row >= -1) {
277
		menu.insertItem(i18n("&Insert row"), this, SLOT(addRow(int)), 0, 0);
Urs Fleisch's avatar
Urs Fleisch committed
278
279
280
281
282
283
284
285
286
287
		menu.setItemParameter(0, row);
	}
	if (row >= 0) {
		menu.insertItem(i18n("&Delete row"), this, SLOT(deleteRow(int)), 0, 1);
		menu.setItemParameter(1, row);
	}
	if (row >= 0) {
		menu.insertItem(i18n("&Clear row"), this, SLOT(clearRow(int)), 0, 2);
		menu.setItemParameter(2, row);
	}
288
#endif
Urs Fleisch's avatar
Urs Fleisch committed
289
290
291
292
	menu.setMouseTracking(true);
	menu.exec(pos);
}

293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
#if QT_VERSION >= 0x040000
/**
 * Display custom context menu.
 *
 * @param pos position where context menu is drawn on screen
 */
void CommandsTable::customContextMenu(const QPoint& pos)
{
	QTableWidgetItem* item = itemAt(pos);
	if (item) {
#if QT_VERSION >= 0x040200
		contextMenu(item->row(), item->column(), mapToGlobal(pos));
#else
		contextMenu(currentRow(), currentColumn(), mapToGlobal(pos));
#endif
	}
}
#else
void CommandsTable::customContextMenu(const QPoint&) {}
#endif

Urs Fleisch's avatar
Urs Fleisch committed
314
315
316
317
318
/**
 * Set the table from the command list.
 *
 * @param cmdList command list
 */
319
void CommandsTable::setCommandList(const MiscConfig::MenuCommandList& cmdList)
Urs Fleisch's avatar
Urs Fleisch committed
320
{
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
#if QT_VERSION >= 0x040000
	setRowCount(0);
	int row = 0;
	for (MiscConfig::MenuCommandList::const_iterator it = cmdList.begin();
			 it != cmdList.end();
			 ++it) {
		if (!(*it).getCommand().isEmpty()) {
			insertRow(row);
			QTableWidgetItem* cti = new QTableWidgetItem;
			if (cti) {
				cti->setCheckState((*it).mustBeConfirmed() ? Qt::Checked : Qt::Unchecked);
				setItem(row, CI_Confirm, cti);
			}
			cti = new QTableWidgetItem;
			if (cti) {
				cti->setCheckState((*it).outputShown() ? Qt::Checked : Qt::Unchecked);
				setItem(row, CI_Output, cti);
			}
			cti = new QTableWidgetItem((*it).getName());
			if (cti) {
				setItem(row, CI_Name, cti);
			}
			cti = new QTableWidgetItem((*it).getCommand());
			if (cti) {
				setItem(row, CI_Command, cti);
			}
			++row;
		}
	}
	if (row == 0) {
		// no commands => show at least one row
		addRow(-1);
	}
#else
Urs Fleisch's avatar
Urs Fleisch committed
355
356
	setNumRows(0);
	int row = 0;
357
	for (MiscConfig::MenuCommandList::const_iterator it = cmdList.begin();
Urs Fleisch's avatar
Urs Fleisch committed
358
359
			 it != cmdList.end();
			 ++it) {
Urs Fleisch's avatar
Urs Fleisch committed
360
		if (!(*it).getCommand().isEmpty()) {
Urs Fleisch's avatar
Urs Fleisch committed
361
			insertRows(row);
362
			QCheckTableItem* cti = new QCheckTableItem(this, "");
Urs Fleisch's avatar
Urs Fleisch committed
363
			if (cti) {
Urs Fleisch's avatar
Urs Fleisch committed
364
365
				cti->setChecked((*it).mustBeConfirmed());
				setItem(row, CI_Confirm, cti);
Urs Fleisch's avatar
Urs Fleisch committed
366
			}
367
			cti = new QCheckTableItem(this, "");
Urs Fleisch's avatar
Urs Fleisch committed
368
369
370
371
372
373
			if (cti) {
				cti->setChecked((*it).outputShown());
				setItem(row, CI_Output, cti);
			}
			setText(row, CI_Name, (*it).getName());
			setText(row, CI_Command, (*it).getCommand());
Urs Fleisch's avatar
Urs Fleisch committed
374
375
376
377
378
			++row;
		}
	}
	if (row == 0) {
		// no commands => show at least one row
379
		addRow(-1);
Urs Fleisch's avatar
Urs Fleisch committed
380
	}
381
#endif
Urs Fleisch's avatar
Urs Fleisch committed
382
383
384
385
386
387
388
}

/**
 * Get the command list from the table.
 *
 * @param cmdList the command list is returned here
 */
389
void CommandsTable::getCommandList(MiscConfig::MenuCommandList& cmdList) const
Urs Fleisch's avatar
Urs Fleisch committed
390
{
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
#if QT_VERSION >= 0x040000
	cmdList.clear();
	int nrRows = rowCount();
	for (int row = 0; row < nrRows; ++row) {
		QTableWidgetItem* twi = item(row, CI_Command);
		if (twi) {
			QString cmd = twi->text();
			if (!cmd.isEmpty()) {
				twi = item(row, CI_Name);
				QString name;
				if (twi) name = twi->text();
				if (name.isEmpty()) {
					name = cmd;
				}
				bool confirm = false;
				bool showOutput = false;
				twi = item(row, CI_Confirm);
				if (twi && twi->checkState() == Qt::Checked) {
					confirm = true;
				}
				twi = item(row, CI_Output);
				if (twi && twi->checkState() == Qt::Checked) {
					showOutput = true;
				}
				cmdList.push_back(MiscConfig::MenuCommand(name, cmd, confirm, showOutput));
			}
		}
	}
#else
Urs Fleisch's avatar
Urs Fleisch committed
420
421
422
	cmdList.clear();
	int nrRows = numRows();
	for (int row = 0; row < nrRows; ++row) {
Urs Fleisch's avatar
Urs Fleisch committed
423
		QString cmd = text(row, CI_Command);
Urs Fleisch's avatar
Urs Fleisch committed
424
		if (!cmd.isEmpty()) {
Urs Fleisch's avatar
Urs Fleisch committed
425
426
427
428
429
430
			QString name = text(row, CI_Name);
			if (name.isEmpty()) {
				name = cmd;
			}
			bool confirm = false;
			bool showOutput = false;
431
432
			QTableItem* ti = item(row, CI_Confirm);
			QCheckTableItem* cti = dynamic_cast<QCheckTableItem*>(ti);
Urs Fleisch's avatar
Urs Fleisch committed
433
434
			if (cti) {
				if (cti->isChecked()) {
Urs Fleisch's avatar
Urs Fleisch committed
435
436
437
438
					confirm = true;
				}
			}
			ti = item(row, CI_Output);
439
			cti = dynamic_cast<QCheckTableItem*>(ti);
Urs Fleisch's avatar
Urs Fleisch committed
440
441
442
			if (cti) {
				if (cti->isChecked()) {
					showOutput = true;
Urs Fleisch's avatar
Urs Fleisch committed
443
444
				}
			}
Urs Fleisch's avatar
Urs Fleisch committed
445
			cmdList.push_back(MiscConfig::MenuCommand(name, cmd, confirm, showOutput));
Urs Fleisch's avatar
Urs Fleisch committed
446
447
		}
	}
448
#endif
Urs Fleisch's avatar
Urs Fleisch committed
449
}