playlistsplitter.cpp 19.4 KB
Newer Older
1 2 3 4 5
/***************************************************************************
                          playlistsplitter.cpp  -  description
                             -------------------
    begin                : Fri Sep 13 2002
    copyright            : (C) 2002 by Scott Wheeler
6
    email                : wheeler@kde.org
7 8 9 10 11 12 13 14 15 16 17
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program 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.                                   *
 *                                                                         *
 ***************************************************************************/

18
#include <kstandarddirs.h>
19
#include <kmessagebox.h>
Nadeem Hasan's avatar
Nadeem Hasan committed
20
#include <klineeditdlg.h>
21 22
#include <kdebug.h>

23
#include <qpopupmenu.h>
24

25
#include "playlistsplitter.h"
26
#include "searchwidget.h"
27
#include "directorylist.h"
28
#include "playlistsearch.h"
29
#include "dynamicplaylist.h"
30
#include "mediafiles.h"
31 32

////////////////////////////////////////////////////////////////////////////////
33
// helper functions
34 35
////////////////////////////////////////////////////////////////////////////////

36
void processEvents()
37
{
38 39 40
    static int processed = 0;
    if(processed == 0)
        kapp->processEvents();
41
    processed = (processed + 1) % 5;
42 43
}

44
////////////////////////////////////////////////////////////////////////////////
45
// public methods
46 47
////////////////////////////////////////////////////////////////////////////////

48
PlaylistSplitter::PlaylistSplitter(QWidget *parent, bool restore, const char *name) :
49
    QSplitter(Qt::Horizontal, parent, name),
50
    m_playingItem(0), m_searchWidget(0), m_dynamicList(0), m_restore(restore),
51
    m_nextPlaylistItem(0)
52
{
53 54
    setupLayout();
    readConfig();
55 56

    m_editor->slotUpdateCollection();
57
    m_playlistBox->initViewMode();
58
}
59

60
PlaylistSplitter::~PlaylistSplitter()
61
{
Scott Wheeler's avatar
Scott Wheeler committed
62
    delete m_dirWatch;
63
    saveConfig();
64 65
}

66
QString PlaylistSplitter::uniquePlaylistName(const QString &startingWith, bool useParenthesis)
67
{
68
    if(!m_playlistBox)
69
	return QString::null;
70

71
    QStringList names = m_playlistBox->names();
72 73 74

    int playlistNumber = 1;

75
    // while the list contains more than zero instances of the generated
76 77
    // string...

78 79 80
    if(useParenthesis) {
	while(names.contains(startingWith + " (" + QString::number(playlistNumber) + ")") != 0)
	    playlistNumber++;
81 82

	return startingWith + " (" + QString::number(playlistNumber) + ")";
83 84 85 86 87
    }
    else
    {
	while(names.contains(startingWith + ' ' + QString::number(playlistNumber)) != 0)
	    playlistNumber++;
88

89
	return startingWith + " " + QString::number(playlistNumber);
90
    }
91 92
}

93
QString PlaylistSplitter::playNextFile(bool random, bool loopPlaylist)
94
{
95 96
    PlaylistItem *i;

97
    // Four basic cases here:  (1) We've asked for a specific next item, (2) play
98
    // the item that's after the currently playing item, (3) play the selected
99
    // item or (4) play the first item in the list.
100

101
    // (1) we've asked for a specific next item
102
    if(m_nextPlaylistItem && m_nextPlaylistItem != m_playingItem) {
103 104 105
        i = m_nextPlaylistItem;
        m_nextPlaylistItem = 0;
    }
106
    // (2) play the item after the currently selected item
107
    else if(m_playingItem) {
108 109
        Playlist *p = static_cast<Playlist *>(m_playingItem->listView());
        i = p->nextItem(m_playingItem, random);
110
        if(!i && loopPlaylist)
111
            i = static_cast<PlaylistItem *>(p->firstChild());
112
    }
113 114
    // (3) play the selected item
    else if(playlistSelection().size() > 0) {
115
        i = playlistSelection().first();
116 117
        if(!i)
            i = static_cast<PlaylistItem *>(visiblePlaylist()->firstChild());
118
    }
119 120 121
    // (4) play the first item in the list
    else
        i = static_cast<PlaylistItem *>(visiblePlaylist()->firstChild());
122

123
    return play(i);
124 125
}

126
QString PlaylistSplitter::playPreviousFile(bool random)
127
{
128
    if(!m_playingItem)
129
	return QString::null;
130

131 132
    Playlist *p = static_cast<Playlist *>(m_playingItem->listView());
    PlaylistItem *i = p->previousItem(m_playingItem, random);
133

134
    return play(i);
135 136
}

137 138 139 140 141 142 143 144 145 146 147 148
void PlaylistSplitter::populatePlayHistoryMenu(QPopupMenu* menu, bool random)
{
    Playlist *p = static_cast<Playlist *>(m_playingItem->listView());
    PlaylistItemList list = p->historyItems(m_playingItem, random);
    menu->clear();
    int i = 0;
    for (PlaylistItemList::iterator it = list.begin(); it != list.end(); ++it)
    {
        menu->insertItem((*it)->tag()->track(), ++i);
    }
}

149 150 151 152 153 154 155 156
QString PlaylistSplitter::playSelectedFile()
{
    if(playlistSelection().isEmpty())
	return QString::null;
    else
	return play(playlistSelection().first());
}

157 158 159 160
QString PlaylistSplitter::playFirstFile()
{
    Playlist *p = visiblePlaylist();
    PlaylistItem *i = static_cast<PlaylistItem *>(p->firstChild());
161

162
    return play(i);
163 164
}

165 166 167 168 169 170 171 172 173
QString PlaylistSplitter::playRandomFile()
{
    Playlist *p = visiblePlaylist();
    PlaylistItem *i = static_cast<PlaylistItem *>(p->firstChild());

    // Not exactly random (the first item won't be taken into account)
    return play(p->nextItem(i, true));
}

174 175
void PlaylistSplitter::stop()
{
176 177
    m_nextPlaylistItem = 0;

178 179 180 181 182
    if(!m_playingItem)
	return;

    Playlist *p = static_cast<Playlist *>(m_playingItem->listView());

183 184 185
    if(p)
	p->setPlaying(m_playingItem, false);

186
    m_playingItem = 0;
187 188 189 190
}

QString PlaylistSplitter::playingArtist() const
{
191 192
    if(m_playingItem)
	return m_playingItem->text(PlaylistItem::ArtistColumn);
193
    else
194
	return QString::null;
195 196 197 198
}

QString PlaylistSplitter::playingTrack() const
{
199 200
    if(m_playingItem)
	return m_playingItem->text(PlaylistItem::TrackColumn);
201
    else
202
	return QString::null;
203 204 205 206
}

QString PlaylistSplitter::playingList() const
{
207 208
    if(m_playingItem)
	return static_cast<Playlist *>(m_playingItem->listView())->name();
209
    else
210
	return QString::null;
211 212
}

213
void PlaylistSplitter::open(const QString &file)
214
{
215 216 217
    if(file.isEmpty())
	return;

218 219 220 221 222
    if(visiblePlaylist() == m_collection ||
       KMessageBox::questionYesNo(this,
				  i18n("Do you want to add this item to the current list or to the collection list?"),
				  QString::null,
				  KGuiItem(i18n("Current")),
223 224
				  KGuiItem(i18n("Collection"))) == KMessageBox::No)
    {
225
	slotAddToPlaylist(file, m_collection);
226
    }
227
    else
228
	slotAddToPlaylist(file, visiblePlaylist());
229 230
}

231
void PlaylistSplitter::open(const QStringList &files)
232
{
233 234
    if(files.isEmpty())
	return;
235 236 237 238 239 240 241

    if(visiblePlaylist() == m_collection ||
       KMessageBox::questionYesNo(this,
				  i18n("Do you want to add these items to the current list or to the collection list?"),
				  QString::null,
				  KGuiItem(i18n("Current")),
				  KGuiItem(i18n("Collection"))) == KMessageBox::No)
242
    {
243
	slotAddToPlaylist(files, m_collection);
244
    }
245
    else
246
	slotAddToPlaylist(files, visiblePlaylist());
247 248 249 250
}

Playlist *PlaylistSplitter::createPlaylist(const QString &name)
{
251
    Playlist *p = new Playlist(m_playlistStack, name.latin1());
252 253
    setupPlaylist(p, true);
    return p;
254 255
}

256 257 258 259
////////////////////////////////////////////////////////////////////////////////
// public slots
////////////////////////////////////////////////////////////////////////////////

260
void PlaylistSplitter::slotOpen()
261
{
262
    open(MediaFiles::openDialog(this));
263 264
}

265
void PlaylistSplitter::slotOpenDirectory()
266
{
267
    DirectoryList *l = new DirectoryList(m_directoryList, this, "directoryList");
268

269
    m_directoryQueue.clear();
270
    m_directoryQueueRemove.clear();
271

272
    connect(l, SIGNAL(signalDirectoryAdded(const QString &)),
273
	    this, SLOT(slotQueueDirectory(const QString &)));
274
    connect(l, SIGNAL(signalDirectoryRemoved(const QString &)),
275
	    this, SLOT(slotQueueDirectoryRemove(const QString &)));
276 277

    if(l->exec() == QDialog::Accepted) {
278
	open(m_directoryQueue);
279 280
	for(QStringList::Iterator it = m_directoryQueue.begin(); it !=  m_directoryQueue.end(); it++)
	    m_dirWatch->addDir(*it, false, true);
281

282
	m_directoryList += m_directoryQueue;
283 284 285

	QStringList::Iterator it = m_directoryQueueRemove.begin();
	for(; it !=  m_directoryQueueRemove.end(); it++) {
286
	    m_dirWatch->removeDir(*it);
287
	    m_directoryList.remove(*it);
288
	}
289 290
    }
}
291

292
Playlist *PlaylistSplitter::slotCreatePlaylist()
293 294 295
{
    bool ok;

296
    // If this text is changed, please also change it in PlaylistBox::duplicate().
297

298
    QString name = KLineEditDlg::getText(i18n("Create New Playlist"),
Nadeem Hasan's avatar
Nadeem Hasan committed
299 300
	i18n("Please enter a name for the new playlist:"),
	uniquePlaylistName(), &ok);
301
    if(ok)
302
	return createPlaylist(name);
303
    else
304
	return 0;
305 306
}

307
void PlaylistSplitter::slotSelectPlaying()
308
{
309
    if(!m_playingItem)
310 311
	return;

312
    Playlist *l = static_cast<Playlist *>(m_playingItem->listView());
313

314 315
    if(!l)
	return;
316

317
    l->clearSelection();
318 319
    l->setSelected(m_playingItem, true);
    l->ensureItemVisible(m_playingItem);
Nadeem Hasan's avatar
Nadeem Hasan committed
320

321 322
    if(l != visiblePlaylist())
	m_playlistBox->raise(l);
323 324
}

325
void PlaylistSplitter::slotDeleteSelectedItems()
326 327 328
{
    Playlist *p = visiblePlaylist();
    if(p)
329
	p->slotDeleteSelectedItems();
330 331
}

332 333 334 335
void PlaylistSplitter::slotAddToPlaylist(const QString &file, Playlist *list)
{
    KApplication::setOverrideCursor(Qt::waitCursor);
    addImpl(file, list);
336
    list->emitNumberOfItemsChanged();
337
    KApplication::restoreOverrideCursor();
Nadeem Hasan's avatar
Nadeem Hasan committed
338

339 340 341 342 343 344 345 346 347
    if(m_editor)
	m_editor->slotUpdateCollection();
}

void PlaylistSplitter::slotAddToPlaylist(const QStringList &files, Playlist *list)
{
    KApplication::setOverrideCursor(Qt::waitCursor);
    for(QStringList::ConstIterator it = files.begin(); it != files.end(); ++it)
        addImpl(*it, list);
348
    list->emitNumberOfItemsChanged();
349 350 351 352 353 354
    KApplication::restoreOverrideCursor();

    if(m_editor)
	m_editor->slotUpdateCollection();
}

355 356 357 358 359 360 361
void PlaylistSplitter::slotSetSearchVisible(bool visible)
{
    m_searchWidget->setShown(visible);
    redisplaySearch();
}


362
void PlaylistSplitter::slotGuessTagInfoFile()
363
{
364 365 366 367 368 369 370 371
    visiblePlaylist()->slotGuessTagInfoFile();
    if(m_editor)
        m_editor->slotRefresh();
}

void PlaylistSplitter::slotGuessTagInfoInternet()
{
    visiblePlaylist()->slotGuessTagInfoInternet();
372 373 374 375
    if(m_editor)
        m_editor->slotRefresh();
}

376 377 378 379 380 381 382
void PlaylistSplitter::slotRenameFile()
{
    visiblePlaylist()->slotRenameFile();
    if(m_editor)
        m_editor->slotRefresh();
}

383 384 385 386 387 388
////////////////////////////////////////////////////////////////////////////////
// private members
////////////////////////////////////////////////////////////////////////////////

void PlaylistSplitter::setupLayout()
{
389 390
    setOpaqueResize(true);

391
    m_playlistBox = new PlaylistBox(this, "playlistBox");
392 393 394 395 396 397

    // Create a splitter to go between the playlists and the editor.

    QSplitter *editorSplitter = new QSplitter(Qt::Vertical, this, "editorSplitter");

    // Create the playlist and the editor.
398

399 400
    m_playlistStack = new QWidgetStack(editorSplitter, "playlistStack");
    m_editor = new TagEditor(editorSplitter, "tagEditor");
401 402 403

    // Make the editor as small as possible (or at least as small as recommended)

404
    editorSplitter->setResizeMode(m_editor, QSplitter::FollowSizeHint);
405

406
    // Make the connection that will update the selected playlist when a
407 408
    // selection is made in the playlist box.

409
    connect(m_playlistBox, SIGNAL(signalCurrentChanged(const PlaylistList &)),
410
	    this, SLOT(slotChangePlaylist(const PlaylistList &)));
411

412
    connect(m_playlistBox, SIGNAL(signalDoubleClicked()), this, SIGNAL(signalListBoxDoubleClicked()));
413

414
    // Create the collection list; this should always exist.  This has a
415
    // slightly different creation process than normal playlists (since it in
416
    // fact is a subclass) so it is created here rather than by using
417
    // slotCreatePlaylist().
418

419
    CollectionList::initialize(m_playlistStack, m_restore);
420 421
    m_collection = CollectionList::instance();
    setupPlaylist(m_collection, true, "folder_sound");
422
    connect(m_collection, SIGNAL(signalCollectionChanged()), m_editor, SLOT(slotUpdateCollection()));
423
    connect(m_collection, SIGNAL(signalRequestPlaylistCreation(const PlaylistItemList &)),
424
	    this, SLOT(slotCreatePlaylist(const PlaylistItemList &)));
425

426 427 428 429

    // Create the search widget -- this must be done after the CollectionList is created.
    m_searchWidget = new SearchWidget(editorSplitter, CollectionList::instance(), "searchWidget");
    editorSplitter->moveToFirst(m_searchWidget);
430
    connect(m_searchWidget, SIGNAL(signalQueryChanged()), this, SLOT(slotShowSearchResults()));
431 432 433
    connect(CollectionList::instance(), SIGNAL(signalVisibleColumnsChanged()),
	    this, SLOT(slotVisibleColumnsChanged()));

434
    // Show the collection on startup.
435
    m_playlistBox->setSelected(0, true);
436 437 438 439
}

void PlaylistSplitter::readConfig()
{
440 441 442 443
    KConfig *config = KGlobal::config();
    { // block for Playlists group
	KConfigGroupSaver saver(config, "Playlists");

444 445 446 447 448 449
	QValueList<int> splitterSizes = config->readIntListEntry("PlaylistSplitterSizes");
	if(splitterSizes.isEmpty()) {
	    splitterSizes.append(100);
	    splitterSizes.append(640);
	}
	setSizes(splitterSizes);
450

451
	if(m_restore) {
452 453 454 455

	    QString playlistsFile = KGlobal::dirs()->saveLocation("appdata") + "playlists";

	    QFile f(playlistsFile);
Nadeem Hasan's avatar
Nadeem Hasan committed
456

457 458 459
	    if(f.open(IO_ReadOnly)) {
		QDataStream s(&f);
		while(!s.atEnd()) {
460
		    Playlist *p = new Playlist(m_playlistStack);
461 462 463 464
		    s >> *p;

		    // check to see if we've alredy loaded this item before continuing

465
		    if(p->fileName().isEmpty() || !m_playlistFiles.insert(p->fileName()))
466 467 468 469
			setupPlaylist(p);
		    else
			delete p;
		}
470
	    }
471

472
	    m_directoryList = config->readListEntry("DirectoryList");
473
	    QTimer::singleShot(0, this, SLOT(slotScanDirectories()));
474 475

	    m_dirWatch = new KDirWatch();
476
	    connect(m_dirWatch, SIGNAL(dirty(const QString &)),
477
		    this, SLOT(slotDirChanged(const QString &)));
478

479 480
	    QStringList::Iterator it = m_directoryList.begin();
            for(; it != m_directoryList.end(); ++it)
481 482 483
		m_dirWatch->addDir(*it, false, true);

	    m_dirWatch->startScan();
484
	}
485 486 487

	// restore the list of hidden and shown columns

488
	if(m_collection) {
489
	    for(int i = 0; i < m_collection->columns(); i++)
490
		m_columnNames.append(m_collection->columnText(i));
491
	}
492

493
    }
494
}
495 496 497 498

void PlaylistSplitter::saveConfig()
{
    KConfig *config = KGlobal::config();
499

500
    // Save the list of open playlists.
Nadeem Hasan's avatar
Nadeem Hasan committed
501

502
    if(m_restore && m_playlistBox) {
503 504 505

	// Start at item 1.  We want to skip the collection list.

506 507
	QString playlistsFile = KGlobal::dirs()->saveLocation("appdata") + "playlists";
	QFile f(playlistsFile);
508

509 510 511 512
	if(f.open(IO_WriteOnly)) {

	    QDataStream s(&f);

513
	    PlaylistList l = m_playlistBox->playlists();
514

515 516
	    for(PlaylistList::Iterator it = l.begin(); it != l.end(); it++)
		s << *(*it);
517

518
	    f.close();
519 520 521
	}
	{ // block for Playlists group
	    KConfigGroupSaver saver(config, "Playlists");
522
	    config->writeEntry("DirectoryList", m_directoryList);
523
	    config->writeEntry("SortColumn", m_collection->sortColumn());
524
	    config->writeEntry("PlaylistSplitterSizes", sizes());
525 526
	}
    }
527 528
}

529 530 531 532 533 534 535 536 537 538 539 540 541
void PlaylistSplitter::addImpl(const QString &file, Playlist *list)
{
    processEvents();
    QFileInfo fileInfo(QDir::cleanDirPath(file));
    if(fileInfo.exists()) {
        if(fileInfo.isDir()) {
            QDir dir(fileInfo.filePath());
            QStringList dirContents=dir.entryList();
            for(QStringList::Iterator it = dirContents.begin(); it != dirContents.end(); ++it)
                if(*it != "." && *it != "..")
                    addImpl(fileInfo.filePath() + QDir::separator() + *it, list);
        }
        else {
542
            if(MediaFiles::isMediaFile(file))
543
		list->createItem(fileInfo, QString::null, 0, false);
544
	    else if(MediaFiles::isPlaylistFile(file))
545 546
		openPlaylist(fileInfo.absFilePath());
        }
Nadeem Hasan's avatar
Nadeem Hasan committed
547
    }
548 549
}

550
void PlaylistSplitter::setupPlaylist(Playlist *p, bool raise, const char *icon)
551
{
552 553 554 555 556 557
    connect(p, SIGNAL(signalSelectionChanged(const PlaylistItemList &)),
	    m_editor, SLOT(slotSetItems(const PlaylistItemList &)));
    connect(p, SIGNAL(signalDoubleClicked()),
	    this, SIGNAL(signalDoubleClicked()));
    connect(p, SIGNAL(signalNumberOfItemsChanged(Playlist *)),
	    this, SLOT(slotPlaylistCountChanged(Playlist *)));
558
    connect(p, SIGNAL(signalAboutToRemove(PlaylistItem *)),
559
	    this, SLOT(slotPlaylistItemRemoved(PlaylistItem *)));
560
    connect(p, SIGNAL(signalFilesDropped(const QStringList &, Playlist *)),
561 562 563
	    this, SLOT(slotAddToPlaylist(const QStringList &, Playlist *)));
    connect(p, SIGNAL(signalSetNext(PlaylistItem *)),
	    this, SLOT(slotSetNextItem(PlaylistItem *)));
564

565 566
    if(icon)
	m_playlistBox->createItem(p, icon, raise);
567

568 569 570 571 572
    if(raise) {
	PlaylistList l;
	l.append(p);
	slotChangePlaylist(l);
    }
573 574
}

575 576 577
Playlist *PlaylistSplitter::openPlaylist(const QString &file)
{
    QFileInfo fileInfo(file);
578 579 580
    if(!fileInfo.exists() ||
       !fileInfo.isFile() ||
       !fileInfo.isReadable() ||
581 582
       m_playlistFiles.insert(fileInfo.absFilePath()))
    {
583
	return 0;
584
    }
585

586
    Playlist *p = new Playlist(file, m_playlistStack, fileInfo.baseName(true).latin1());
587
    setupPlaylist(p);
588
    return p;
589 590
}

591 592 593 594 595 596 597
QString PlaylistSplitter::play(PlaylistItem *item)
{
    stop();

    if(!item)
	return QString::null;

598 599 600 601
    Playlist *p = static_cast<Playlist *>(item->listView());

    p->setPlaying(item, true);

602 603 604 605 606
    m_playingItem = item;

    return item->absFilePath();
}

607 608 609 610 611 612 613 614 615 616
void PlaylistSplitter::redisplaySearch()
{
    if(!m_searchWidget->isVisible() || visiblePlaylist()->search().isEmpty())
	visiblePlaylist()->setItemsVisible(visiblePlaylist()->items(), true);
    else {
	Playlist::setItemsVisible(visiblePlaylist()->search().matchedItems(), true);
	Playlist::setItemsVisible(visiblePlaylist()->search().unmatchedItems(), false);
    }
}

617 618 619 620
////////////////////////////////////////////////////////////////////////////////
// private slots
////////////////////////////////////////////////////////////////////////////////

621
void PlaylistSplitter::slotChangePlaylist(const PlaylistList &l)
622
{
623 624
    if(l.isEmpty()) {
	emit signalPlaylistChanged();
625
	return;
626
    }
627

628 629
    Playlist *current = m_dynamicList;

630
    m_nextPlaylistItem = 0;
631 632 633 634
    if(l.count() == 1) {
	m_playlistStack->raiseWidget(l.first());
	m_editor->slotSetItems(playlistSelection());
	m_dynamicList = 0;
635 636 637 638 639

	if(m_searchWidget) {
	    m_searchWidget->setSearch(l.first()->search());
	    redisplaySearch();
	}
640 641
    }
    else {
642
	m_dynamicList = new DynamicPlaylist(l, m_playlistStack, i18n("Dynamic List"));
643 644 645 646 647
	setupPlaylist(m_dynamicList, true, 0);
    }

    if(current)
	delete current;
648 649

    emit signalPlaylistChanged();
650 651
}

652
void PlaylistSplitter::slotPlaylistCountChanged(Playlist *p)
653
{
654 655
    if(p && p == m_playlistStack->visibleWidget())
	emit signalSelectedPlaylistCountChanged(p->childCount());
656 657
}

658
void PlaylistSplitter::slotPlaylistItemRemoved(PlaylistItem *item)
659
{
660 661
    if(item == m_playingItem)
	m_playingItem = 0;
662 663 664

    if(item == m_nextPlaylistItem)
	m_nextPlaylistItem = 0;
665 666
}

667
void PlaylistSplitter::slotCreatePlaylist(const PlaylistItemList &items)
668
{
669 670 671
    if(items.isEmpty())
	return;

672
    Playlist *playlist = slotCreatePlaylist();
673

674
    if(!playlist)
675
        return;
676

677
    playlist->createItems(items);
678
    m_playlistBox->initViewMode();
679 680
}

681
void PlaylistSplitter::slotShowSearchResults()
682 683 684 685
{
    PlaylistList playlists;
    playlists.append(visiblePlaylist());

686
    PlaylistSearch search = m_searchWidget->search(playlists);
687

688 689
    visiblePlaylist()->setSearch(search);
    redisplaySearch();
690 691
}

692 693 694 695 696
void PlaylistSplitter::slotVisibleColumnsChanged()
{
    m_searchWidget->slotUpdateColumns();
    m_searchWidget->slotQueryChanged();
    if(m_searchWidget->searchedColumns(0).count() > 1)
697
        slotShowSearchResults();
698 699
}

700
#include "playlistsplitter.moc"
Nadeem Hasan's avatar
Nadeem Hasan committed
701 702

// vim:ts=8