filelistitem.cpp 12 KB
Newer Older
Urs Fleisch's avatar
Urs Fleisch committed
1
2
3
4
5
6
7
/**
 * \file filelistitem.cpp
 * Item in filelist.
 *
 * \b Project: Kid3
 * \author Urs Fleisch
 * \date 02 Oct 2006
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 *
 * Copyright (C) 2006-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 "filelistitem.h"
28
#include "filelist.h"
Urs Fleisch's avatar
Urs Fleisch committed
29
#include "taggedfile.h"
30
#include "dirinfo.h"
31
#include "kid3.h"
Urs Fleisch's avatar
Urs Fleisch committed
32
33
34

#include <qapplication.h>
#include <qpainter.h>
Urs Fleisch's avatar
Urs Fleisch committed
35
#include <qpixmap.h>
36
#include <qfileinfo.h>
Urs Fleisch's avatar
Urs Fleisch committed
37
38

/** Empty pixmap, will be allocated in constructor */
39
QPixmap* FileListItem::nullPixmap = 0;
Urs Fleisch's avatar
Urs Fleisch committed
40
/** Pixmap for modified file, will be allocated in constructor */
41
QPixmap* FileListItem::modifiedPixmap = 0;
Urs Fleisch's avatar
Urs Fleisch committed
42
/** Pixmap for V1V2, will be allocated in constructor */
43
QPixmap* FileListItem::v1v2Pixmap = 0;
Urs Fleisch's avatar
Urs Fleisch committed
44
/** Pixmap for V1, will be allocated in constructor */
45
QPixmap* FileListItem::v1Pixmap = 0;
Urs Fleisch's avatar
Urs Fleisch committed
46
/** Pixmap for V2, will be allocated in constructor */
47
QPixmap* FileListItem::v2Pixmap = 0;
Urs Fleisch's avatar
Urs Fleisch committed
48
/** Pixmap for "no tag", will be allocated in constructor */
49
50
51
52
53
QPixmap* FileListItem::notagPixmap = 0;
/** Pixmap for closed folder, will be allocated in constructor */
QPixmap* FileListItem::folderClosedPixmap = 0;
/** Pixmap for open folder, will be allocated in constructor */
QPixmap* FileListItem::folderOpenPixmap = 0;
Urs Fleisch's avatar
Urs Fleisch committed
54
55
56
57

/* The bitmaps are stored here instead of using KDE bitmaps to make
   it work for the Qt only versions. */
/** picture for modified pixmap */
58
static const char* const modified_xpm[] = {
Urs Fleisch's avatar
Urs Fleisch committed
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
	"16 16 33 1",
	". c None",
	"B c None",
	"A c None",
	"C c None",
	"D c None",
	"E c None",
	"# c #000000",
	"b c #006562",
	"j c #414041",
	"x c #525552",
	"f c #529594",
	"e c #52959c",
	"w c #5a555a",
	"v c #626162",
	"u c #626562",
	"r c #737173",
	"p c #737573",
	"q c #7b757b",
	"o c #838183",
	"m c #838583",
	"z c #8b8d8b",
	"l c #949194",
	"k c #9c959c",
	"i c #a4a1a4",
	"h c #a4a5a4",
	"y c #b4b6b4",
	"g c #bdb6bd",
	"a c #c5c2c5",
	"s c #c5c6c5",
	"c c #cdc6cd",
	"t c #dedade",
	"n c #eeeaee",
	"d c #ffffff",
	".......##.......",
	"......#ab#......",
	".....#cbde#.....",
	"....#abdddf#....",
	"...#gbddddde#...",
	"..#hijddddddf#..",
	".#kjkljdddddd##.",
	"#mjnjmojddddjma#",
	"#jnpnjqrjddjqs#.",
	"#drtttjuvjjua#..",
	".#dasajjwxws#...",
	"..#dyjzljxa#...A",
	"...#jrrjws#...AB",
	"....#cjxa#...ACB",
	".....#cs#...ADE.",
	"......##...ABB.."
};

/** picture for empty pixmap */
112
static const char* const null_xpm[] = {
Urs Fleisch's avatar
Urs Fleisch committed
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
	"16 16 2 1",
	"# c None",
	". c None",
	".#.#.#.#.#.#.#.#",
	"#.#.#.#.#.#.#.#.",
	".#.#.#.#.#.#.#.#",
	"#.#.#.#.#.#.#.#.",
	".#.#.#.#.#.#.#.#",
	"#.#.#.#.#.#.#.#.",
	".#.#.#.#.#.#.#.#",
	"#.#.#.#.#.#.#.#.",
	".#.#.#.#.#.#.#.#",
	"#.#.#.#.#.#.#.#.",
	".#.#.#.#.#.#.#.#",
	"#.#.#.#.#.#.#.#.",
	".#.#.#.#.#.#.#.#",
	"#.#.#.#.#.#.#.#.",
	".#.#.#.#.#.#.#.#",
	"#.#.#.#.#.#.#.#."
};

134
135
/** picture with V1 and V2 */
static const char* const v1v2_xpm[] = {
Urs Fleisch's avatar
Urs Fleisch committed
136
	"16 16 3 1",
Urs Fleisch's avatar
Urs Fleisch committed
137
138
139
	"  c None",
	". c #FFFFFF",
	"+ c #000000",
140
141
142
143
144
145
146
147
148
149
150
151
152
153
	"                ",
	"  ..  ..   .    ",
	"  .+  .+  .+    ",
	"  .+  .+ .++    ",
	"   .+.+ .+.+    ",
	"   .+.+   .+    ",
	"    .+    .+    ",
	"                ",
	"  ..  ..  ..    ",
	"  .+  .+ .++.   ",
	"  .+  .+.+ .+   ",
	"   .+.+   .+    ",
	"   .+.+  .+..   ",
	"    .+  .++++   ",
Urs Fleisch's avatar
Urs Fleisch committed
154
155
156
	"                ",
	"                "};

157
158
/** picture with V1 */
static const char* const v1_xpm[] = {
Urs Fleisch's avatar
Urs Fleisch committed
159
	"16 16 3 1",
Urs Fleisch's avatar
Urs Fleisch committed
160
161
162
	"  c None",
	". c #FFFFFF",
	"+ c #000000",
Urs Fleisch's avatar
Urs Fleisch committed
163
	"                ",
164
165
166
167
168
169
	"  ..  ..   .    ",
	"  .+  .+  .+    ",
	"  .+  .+ .++    ",
	"   .+.+ .+.+    ",
	"   .+.+   .+    ",
	"    .+    .+    ",
Urs Fleisch's avatar
Urs Fleisch committed
170
171
172
173
174
175
176
177
178
179
	"                ",
	"                ",
	"                ",
	"                ",
	"                ",
	"                ",
	"                ",
	"                ",
	"                "};

180
181
/** picture with V2 */
static const char* const v2_xpm[] = {
Urs Fleisch's avatar
Urs Fleisch committed
182
	"16 16 3 1",
Urs Fleisch's avatar
Urs Fleisch committed
183
184
185
	"  c None",
	". c #FFFFFF",
	"+ c #000000",
Urs Fleisch's avatar
Urs Fleisch committed
186
187
188
189
190
191
192
193
	"                ",
	"                ",
	"                ",
	"                ",
	"                ",
	"                ",
	"                ",
	"                ",
194
195
196
197
198
199
	"  ..  ..  ..    ",
	"  .+  .+ .++.   ",
	"  .+  .+.+ .+   ",
	"   .+.+   .+    ",
	"   .+.+  .+..   ",
	"    .+  .++++   ",
Urs Fleisch's avatar
Urs Fleisch committed
200
201
202
	"                ",
	"                "};

203
204
/** picture with NO TAG */
static const char* const notag_xpm[] = {
Urs Fleisch's avatar
Urs Fleisch committed
205
	"16 16 3 1",
Urs Fleisch's avatar
Urs Fleisch committed
206
207
208
	"  c None",
	". c #FFFFFF",
	"+ c #000000",
209
210
211
212
213
214
215
216
217
218
219
220
221
222
	"                ",
	"  ..  ..  ..    ",
	"  .+. .+ .++.   ",
	"  .++..+.+ .+   ",
	"  .+.+.+.+ .+   ",
	"  .+ .++.+..+   ",
	"  .+  .+ .++    ",
	"                ",
	" ....  .   ..   ",
	" .+++ .+. .++   ",
	"  .+ .+.+.+ ..  ",
	"  .+ .+++.+.++  ",
	"  .+ .+.+.+..+  ",
	"  .+ .+.+ .++   ",
Urs Fleisch's avatar
Urs Fleisch committed
223
224
225
	"                ",
	"                "};

226
227
228
/** picture with closed folder */
static const char* folder_closed_xpm[]={
	"16 16 10 1",
Urs Fleisch's avatar
Urs Fleisch committed
229
230
231
232
233
234
235
236
237
238
	"  c #0E279A",
	". c #2852AF",
	"+ c #2B66D3",
	"@ c #2A83FE",
	"# c #627CB1",
	"$ c #5FA1FC",
	"% c #B0B2CA",
	"& c #89BEF9",
	"* c #CDE9FD",
	"= c #FCFFFC",
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
	"==++++++========",
	"=+======+=======",
	"+==*=*==#++++++=",
	"+**=*****=*=*=*+",
	".********+++++++",
	".*******+&====&+",
	".*&+++++&=&&&&&+",
	".&+$=*===$$$$$$+",
	".&+@$@$@$$$$$@$+",
	".&.@@@@@@@@@@@@ ",
	".& @@@@@@@@@@@@ ",
	".& ===========% ",
	".& ===========% ",
	".$ %%%%%%%%%%%% ",
	"=.             =",
	"================"};

/** picture with open folder */
static const char* folder_open_xpm[]={
	"16 16 10 1",
Urs Fleisch's avatar
Urs Fleisch committed
259
260
261
262
263
264
265
266
267
268
	"  c #0E279A",
	". c #2852AF",
	"+ c #2B66D3",
	"@ c #2A83FE",
	"# c #627CB1",
	"$ c #5FA1FC",
	"% c #B0B2CA",
	"& c #89BEF9",
	"* c #CDE9FD",
	"= c #FCFFFC",
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
	"==++++++========",
	"=+======+=======",
	"+==*=*==#++++++=",
	"+**=*****=*=*=*+",
	".********+++++++",
	".*******+&====*+",
	".*&+++++#=&&&&&+",
	".&+$=*==*$$$$$$+",
	".&+$$@$$@$$$$$@ ",
	".$+@@@@@@@@@@@@ ",
	"..+@@@@@@@@@@@+ ",
	".+%===========.=",
	". %==========% =",
	". %%%%%%%%%%%% =",
	"=              =",
	"================"};
Urs Fleisch's avatar
Urs Fleisch committed
285
286
287
288

/**
 * Constructor.
 *
289
290
291
 * @param parent parent file list
 * @param after  this item is inserted after item @a after
 * @param file   tagged file (will be owned by this item)
Urs Fleisch's avatar
Urs Fleisch committed
292
 */
293
294
FileListItem::FileListItem(FileList* parent, FileListItem* after,
													 TaggedFile* file) :
295
296
297
298
299
300
#if QT_VERSION >= 0x040000
	QTreeWidgetItem(parent, after),
#else
	QListViewItem(parent, after),
#endif
	m_file(file), m_dirInfo(0)
301
302
303
304
305
306
307
308
309
310
311
312
313
{
	init();
}

/**
 * Constructor for non top-level items.
 *
 * @param parent parent file list item
 * @param after  this item is inserted after item @a after
 * @param file   tagged file (will be owned by this item)
 */
FileListItem::FileListItem(FileListItem* parent, FileListItem* after,
													 TaggedFile* file) :
314
315
316
317
318
319
#if QT_VERSION >= 0x040000
	QTreeWidgetItem(parent, after), m_isOpen(false),
#else
	QListViewItem(parent, after),
#endif
	m_file(file), m_dirInfo(0)
320
321
322
323
324
325
326
327
328
{
	init();
}

/**
 * Initialize file list item.
 * Common initialization for all constructors.
 */
void FileListItem::init()
Urs Fleisch's avatar
Urs Fleisch committed
329
330
331
{
	setInSelection(false);
	if (m_file) {
332
		setText(0, m_file->getFilename());
Urs Fleisch's avatar
Urs Fleisch committed
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
	}

	// this two objects should be destructed when the program terminates.
	// static QPixmap objects are not possible:
	// "QPaintDevice: Must construct a QApplication before a QPaintDevice"
	if (!nullPixmap) {
		nullPixmap = new QPixmap((const char **)null_xpm);
	}
	if (!modifiedPixmap) {
		modifiedPixmap = new QPixmap((const char **)modified_xpm);
	}
	if (!v1v2Pixmap) {
		v1v2Pixmap = new QPixmap((const char **)v1v2_xpm);
	}
	if (!v1Pixmap) {
		v1Pixmap = new QPixmap((const char **)v1_xpm);
	}
	if (!v2Pixmap) {
		v2Pixmap = new QPixmap((const char **)v2_xpm);
	}
	if (!notagPixmap) {
		notagPixmap = new QPixmap((const char **)notag_xpm);
	}
356
357
358
359
360
361
362
363
	if (!folderClosedPixmap) {
		folderClosedPixmap = new QPixmap((const char **)folder_closed_xpm);
	}
	if (!folderOpenPixmap) {
		folderOpenPixmap = new QPixmap((const char **)folder_open_xpm);
	}

	updateIcons();
Urs Fleisch's avatar
Urs Fleisch committed
364
365
366
367
368
369
370
371
}

/**
 * Destructor.
 */
FileListItem::~FileListItem()
{
	delete m_file;
372
373
374
	delete m_dirInfo;
}

375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
#if QT_VERSION >= 0x040000
/**
 * Opens or closes an item.
 *
 * @param o true to open
 */
void FileListItem::setOpen(bool o)
{
	if (m_dirInfo) {
		m_isOpen = o;
		setIcon(0, o ? *folderOpenPixmap : *folderClosedPixmap);

		if (o  && !childCount()) {
			treeWidget()->setUpdatesEnabled(false);
			FileList::readSubDirectory(m_dirInfo, this, 0);
			treeWidget()->setUpdatesEnabled(true);
		}
		updateIcons();
	}
}
#else
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
/**
 * Paints the contents of one column of an item.
 *
 * @param p      painter
 * @param cg     color group
 * @param column number of column
 * @param width  width
 * @param align  alignment
 */
void FileListItem::paintCell(QPainter* p, const QColorGroup& cg,
														 int column, int width, int align)
{
	if (Kid3App::s_miscCfg.m_markTruncations &&
			column == 0 && m_file && m_file->getTruncationFlags() != 0) {
		QColorGroup g(cg);
		g.setColor(QColorGroup::Base, Qt::red);
412
		QListViewItem::paintCell(p, g, column, width, align);
413
	} else {
414
		QListViewItem::paintCell(p, cg, column, width, align);
415
416
417
	}
}

418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
/**
 * Opens or closes an item.
 *
 * @param o true to open
 */
void FileListItem::setOpen(bool o)
{
	if (m_dirInfo) {
		setPixmap(0, o ? *folderOpenPixmap : *folderClosedPixmap);

		if (o && !childCount()) {
			listView()->setUpdatesEnabled(false);
			FileList::readSubDirectory(m_dirInfo, this, 0);
			listView()->setUpdatesEnabled(true);
		}
		updateIcons();
	}
	QListViewItem::setOpen(o);
}

/**
 * Called before showing the item.
 */
void FileListItem::setup()
{
	if (!m_file) {
		setExpandable(true);
	}
	QListViewItem::setup();
Urs Fleisch's avatar
Urs Fleisch committed
447
}
448
#endif
Urs Fleisch's avatar
Urs Fleisch committed
449
450
451
452
453
454
455
456
457
458
459
460
461
462

/**
 * Set tagged file.
 * The item takes ownership of this file and the old file is deleted.
 *
 * @param file tagged file.
 */
void FileListItem::setFile(TaggedFile* file)
{
	if (m_file) {
		delete m_file;
	}
	m_file = file;
	if (m_file) {
463
		setText(0, m_file->getFilename());
Urs Fleisch's avatar
Urs Fleisch committed
464
	}
465
	updateIcons();
Urs Fleisch's avatar
Urs Fleisch committed
466
467
468
}

/**
469
470
471
472
473
 * Set directory information.
 * An item can represent a file (file is set) or
 * a directory (directory information is set).
 * The item takes ownership of this directory information
 * and the old information is deleted.
Urs Fleisch's avatar
Urs Fleisch committed
474
 *
475
 * @param dirInfo directory information
Urs Fleisch's avatar
Urs Fleisch committed
476
 */
477
void FileListItem::setDirInfo(DirInfo* dirInfo)
Urs Fleisch's avatar
Urs Fleisch committed
478
{
479
480
481
482
483
484
485
486
487
	if (m_dirInfo) {
		delete m_dirInfo;
	}
	m_dirInfo = dirInfo;
	if (m_dirInfo) {
		QFileInfo fi(m_dirInfo->getDirname());
		setText(0, fi.fileName());
		setOpen(false);
	}
Urs Fleisch's avatar
Urs Fleisch committed
488
489
490
}

/**
491
 * Update the icons according to the modificaton state and the tags present.
Urs Fleisch's avatar
Urs Fleisch committed
492
 */
493
void FileListItem::updateIcons()
Urs Fleisch's avatar
Urs Fleisch committed
494
{
495
496
	if (m_file) {
		if (m_file->isChanged()) {
497
			QCM_setIcon(0, *modifiedPixmap);
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
		} else {
			static const QPixmap* tagpm[] = {
				notagPixmap, v1Pixmap, v2Pixmap, v1v2Pixmap, nullPixmap
			};
			int tagpmIdx;
			if (!m_file->isTagInformationRead()) {
				tagpmIdx = 4;
			} else {
				tagpmIdx = 0;
				if (m_file->hasTagV1()) {
					tagpmIdx |= 1;
				}
				if (m_file->hasTagV2()) {
					tagpmIdx |= 2;
				}
			}
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
			QCM_setIcon(0, *tagpm[tagpmIdx]);
		}
#if QT_VERSION >= 0x040200
		if (Kid3App::s_miscCfg.m_markTruncations &&
				m_file->getTruncationFlags() != 0) {
			setBackground(0, Qt::red);
		} else {
			setBackground(0, Qt::NoBrush);
		}
#elif QT_VERSION >= 0x040000
		if (Kid3App::s_miscCfg.m_markTruncations &&
				m_file->getTruncationFlags() != 0) {
			setBackgroundColor(0, Qt::red);
		} else {
			setBackgroundColor(0, QColor());
529
		}
530
#endif
Urs Fleisch's avatar
Urs Fleisch committed
531
532
533
534
	}
}

/**
535
 * Update the text according to the file name.
Urs Fleisch's avatar
Urs Fleisch committed
536
 */
537
void FileListItem::updateText()
Urs Fleisch's avatar
Urs Fleisch committed
538
{
539
540
	if (m_file) {
		setText(0, m_file->getFilename());
Urs Fleisch's avatar
Urs Fleisch committed
541
542
	}
}
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558

/**
 * Set directory name.
 * Sets a new directory name if the item represents a directory.
 *
 * @param dirName new directory name
 */
void FileListItem::setDirName(const QString& dirName)
{
	if (m_dirInfo) {
		m_dirInfo->setDirname(dirName);
		QFileInfo fi(dirName);
		setText(0, fi.fileName());
		setOpen(false);
	}
}