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

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

16 17
#include "playlistsplitter.h"

18
#include <kicon.h>
19
#include <kaction.h>
20
#include <kglobal.h>
21
#include <kactioncollection.h>
22
#include <kdebug.h>
Laurent Montel's avatar
Poirt  
Laurent Montel committed
23
#include <ktoggleaction.h>
24
#include <kconfiggroup.h>
25

26
#include <QEvent>
Laurent Montel's avatar
Laurent Montel committed
27
#include <QVBoxLayout>
28
#include <QList>
29
#include <Q3WidgetStack>
30
#include <QSizePolicy>
31

32
#include "searchwidget.h"
33
#include "playlistsearch.h"
34
#include "actioncollection.h"
35 36
#include "tageditor.h"
#include "collectionlist.h"
37
#include "playermanager.h"
38
#include "nowplaying.h"
39
#include "playlistbox.h"
40

41
////////////////////////////////////////////////////////////////////////////////
42
// public methods
43 44
////////////////////////////////////////////////////////////////////////////////

45
PlaylistSplitter::PlaylistSplitter(QWidget *parent, const char *name) :
46
    QSplitter(Qt::Horizontal, parent),
47
    m_newVisible(0),
48 49 50 51
    m_playlistBox(0),
    m_searchWidget(0),
    m_playlistStack(0),
    m_editor(0)
52
{
53 54
    setObjectName(name);

55
    setupActions();
56 57
    setupLayout();
    readConfig();
58 59

    m_editor->slotUpdateCollection();
60
    m_editor->setupObservers();
61
}
62

63
PlaylistSplitter::~PlaylistSplitter()
64
{
65
    saveConfig();
66 67 68 69 70

    // Since we want to ensure that the shutdown process for the PlaylistCollection
    // (a base class for PlaylistBox) has a chance to write the playlists to disk
    // before they are deleted we're explicitly deleting the PlaylistBox here.

71
    delete m_playlistBox;
72 73
}

74 75 76 77 78
PlaylistInterface *PlaylistSplitter::playlist() const
{
    return m_playlistBox;
}

79 80 81 82 83 84 85 86 87
bool PlaylistSplitter::eventFilter(QObject *, QEvent *event)
{
    if(event->type() == FocusUpEvent::id) {
        m_searchWidget->setFocus();
        return true;
    }
    return false;
}

88 89 90 91 92 93 94 95 96
////////////////////////////////////////////////////////////////////////////////
// public slots
////////////////////////////////////////////////////////////////////////////////

void PlaylistSplitter::setFocus()
{
    m_searchWidget->setFocus();
}

97 98 99 100 101
void PlaylistSplitter::slotFocusCurrentPlaylist()
{
    Playlist *playlist = m_playlistBox->visiblePlaylist();

    if(playlist) {
102
        playlist->setFocus();
Laurent Montel's avatar
Laurent Montel committed
103
        playlist->K3ListView::selectAll(false);
104

105
        // Select the top visible (and matching) item.
106

107
        PlaylistItem *item = static_cast<PlaylistItem *>(playlist->itemAt(QPoint(0, 0)));
108

109 110
        if(!item)
            return;
111

112 113
        // A little bit of a hack to make QListView repaint things properly.  Switch
        // to single selection mode, set the selection and then switch back.
114

Laurent Montel's avatar
Laurent Montel committed
115
        playlist->setSelectionMode(Q3ListView::Single);
116

117 118
        playlist->markItemSelected(item, true);
        playlist->setCurrentItem(item);
119

Laurent Montel's avatar
Laurent Montel committed
120
        playlist->setSelectionMode(Q3ListView::Extended);
121 122 123
    }
}

124
////////////////////////////////////////////////////////////////////////////////
125
// private members
126 127
////////////////////////////////////////////////////////////////////////////////

128 129 130 131 132
Playlist *PlaylistSplitter::visiblePlaylist() const
{
    return m_newVisible ? m_newVisible : m_playlistBox->visiblePlaylist();
}

133
void PlaylistSplitter::setupActions()
134
{
135
    KActionCollection* coll = ActionCollection::actions();
136
    KToggleAction *showSearch =
Pino Toscano's avatar
Pino Toscano committed
137
	 new KToggleAction(KIcon("edit-find"), i18n("Show &Search Bar"), this);
138 139
    coll->addAction("showSearch", showSearch);

Laurent Montel's avatar
Laurent Montel committed
140
    KAction *act = new KAction(KIcon("edit-clear"), i18n("Edit Track Search"), this);
141
    coll->addAction("editTrackSearch", act);
142 143
    act->setShortcut(Qt::Key_F6);
    connect(act, SIGNAL(triggered(bool)), SLOT(setFocus()));
144 145
}

146 147
void PlaylistSplitter::setupLayout()
{
148
    setOpaqueResize(false);
149

Michael Pyne's avatar
Michael Pyne committed
150 151 152 153
    // Disable the GUI until startup is complete (as indicated by PlaylistBox)

    setEnabled(false);

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

156 157
    QSplitter *editorSplitter = new QSplitter(Qt::Vertical, this);
    editorSplitter->setObjectName("editorSplitter");
158 159

    // Create the playlist and the editor.
160

161 162 163
    QWidget *top = new QWidget(editorSplitter);
    QVBoxLayout *topLayout = new QVBoxLayout(top);

Laurent Montel's avatar
Laurent Montel committed
164
    m_playlistStack = new Q3WidgetStack(top, "playlistStack");
165
    m_playlistStack->installEventFilter(this);
166
    m_playlistStack->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
167

168
    connect(m_playlistStack, SIGNAL(aboutToShow(QWidget *)), this, SLOT(slotPlaylistChanged(QWidget *)));
169

Dirk Mueller's avatar
Dirk Mueller committed
170 171
    m_editor = new TagEditor(editorSplitter);
    m_editor->setObjectName("TagEditor");
172 173 174

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

175 176
    editorSplitter->setStretchFactor(editorSplitter->indexOf(m_editor), 0);
    editorSplitter->setStretchFactor(editorSplitter->indexOf(top), 1);
177

178
    // Create the PlaylistBox
179

180
    m_playlistBox = new PlaylistBox(this, m_playlistStack);
181
    m_playlistBox->setObjectName( "playlistBox" );
182

183 184
    connect(m_playlistBox->object(), SIGNAL(signalSelectedItemsChanged()),
            this, SLOT(slotPlaylistSelectionChanged()));
185 186
    connect(m_playlistBox, SIGNAL(signalPlaylistDestroyed(Playlist *)),
            m_editor, SLOT(slotPlaylistDestroyed(Playlist *)));
Michael Pyne's avatar
Michael Pyne committed
187
    connect(m_playlistBox, SIGNAL(startupComplete()), SLOT(slotEnable()));
188

189
    insertWidget(0, m_playlistBox);
190 191 192

    connect(CollectionList::instance(), SIGNAL(signalCollectionChanged()),
            m_editor, SLOT(slotUpdateCollection()));
193

194
    NowPlaying *nowPlaying = new NowPlaying(top, m_playlistBox);
195

196
    // Create the search widget -- this must be done after the CollectionList is created.
197

198
    m_searchWidget = new SearchWidget(top);
199 200
    connect(m_searchWidget, SIGNAL(signalQueryChanged()),
            this, SLOT(slotShowSearchResults()));
201 202
    connect(m_searchWidget, SIGNAL(signalDownPressed()),
            this, SLOT(slotFocusCurrentPlaylist()));
203 204 205 206
    connect(m_searchWidget, SIGNAL(signalAdvancedSearchClicked()),
            m_playlistBox->object(), SLOT(slotCreateSearchPlaylist()));
    connect(m_searchWidget, SIGNAL(signalShown(bool)),
            m_playlistBox->object(), SLOT(slotSetSearchEnabled(bool)));
207
    connect(ActionCollection::action<KToggleAction>("showSearch"), SIGNAL(toggled(bool)),
208
            m_searchWidget, SLOT(setEnabled(bool)));
209

210
    topLayout->addWidget(nowPlaying);
211
    topLayout->addWidget(m_searchWidget);
212
    topLayout->addWidget(m_playlistStack, 1);
213

214
    // Show the collection on startup.
215
    m_playlistBox->setSelected(0, true);
216 217 218 219
}

void PlaylistSplitter::readConfig()
{
220
    KConfigGroup config(KGlobal::config(), "Splitter");
221

222
    QList<int> splitterSizes = config.readEntry("PlaylistSplitterSizes",QList<int>());
223 224 225
    if(splitterSizes.isEmpty()) {
        splitterSizes.append(100);
        splitterSizes.append(640);
226
    }
227
    setSizes(splitterSizes);
228

229
    bool showSearch = config.readEntry("ShowSearch", true);
230
    ActionCollection::action<KToggleAction>("showSearch")->setChecked(showSearch);
231
    m_searchWidget->setHidden(!showSearch);
232 233
}

234
void PlaylistSplitter::saveConfig()
235
{
236 237
    KConfigGroup config(KGlobal::config(), "Splitter");
    config.writeEntry("PlaylistSplitterSizes", sizes());
238
    config.writeEntry("ShowSearch", ActionCollection::action<KToggleAction>("showSearch")->isChecked());
239 240
}

241
void PlaylistSplitter::slotShowSearchResults()
242 243 244
{
    PlaylistList playlists;
    playlists.append(visiblePlaylist());
245 246
    PlaylistSearch search = m_searchWidget->search(playlists);
    visiblePlaylist()->setSearch(search);
247 248
}

249
void PlaylistSplitter::slotPlaylistSelectionChanged()
250
{
251
    m_editor->slotSetItems(visiblePlaylist()->selectedItems());
252 253
}

254
void PlaylistSplitter::slotPlaylistChanged(QWidget *w)
255
{
256 257
    Playlist *p = dynamic_cast<Playlist *>(w);

258
    if(!p)
259
        return;
260 261 262 263

    m_newVisible = p;
    m_searchWidget->setSearch(p->search());
    m_newVisible = 0;
264 265
}

Michael Pyne's avatar
Michael Pyne committed
266 267 268 269 270
void PlaylistSplitter::slotEnable()
{
    setEnabled(true); // Ready to go.
}

271
#include "playlistsplitter.moc"
272 273

// vim: set et sw=4 tw=0 sta: