Commit c8f53250 authored by Michael Pyne's avatar Michael Pyne

JuK optimizapalooza!

* Add whatever X-DBUS-foo line KUniqueApplication says we need.
* Restructure the startup sequence to postpone all the hard work until after the GUI is setup
  as much as possible to allow passing our reply over DBUS ASAP.
* Don't call hasCover from PlaylistItem like, ever.  I made CoverInfo::hasCover() take longer
  when I added support for APIC frames but didn't catch all unnecessary instances of their use
  last time.  Luckily this is the big win and is backportable.
* Also, don't force CoverInfo::coverId() to call hasCover() for no reason.

Hopefully this should remove the egregrious Plasma freeze-ups while starting but even after
returning from KUniqueApplication::newInstance() quickly it seems to take a while for the reply
to go over the D-BUS...

svn path=/trunk/KDE/kdemultimedia/juk/; revision=851610
parent b3bd2756
......@@ -55,21 +55,17 @@ CollectionList *CollectionList::instance()
return m_list;
}
void CollectionList::initialize(PlaylistCollection *collection)
void CollectionList::loadCachedItems()
{
if(m_list)
if(!m_list)
return;
// We have to delay initilaization here because dynamic_cast or comparing to
// the collection instance won't work in the PlaylistBox::Item initialization
// won't work until the CollectionList is fully constructed.
m_list = new CollectionList(collection);
m_list->setName(i18n("Collection List"));
FileHandleHash::Iterator end = Cache::instance()->end();
for(FileHandleHash::Iterator it = Cache::instance()->begin(); it != end; ++it)
new CollectionListItem(*it);
FileHandleHash::ConstIterator end = Cache::instance()->constEnd();
for(FileHandleHash::ConstIterator it = Cache::instance()->constBegin(); it != end; ++it) {
// This may have already been created via a loaded playlist.
if(!m_itemsDict.contains(it.key()))
new CollectionListItem(*it);
}
SplashScreen::update();
......@@ -86,6 +82,21 @@ void CollectionList::initialize(PlaylistCollection *collection)
m_list->sort();
SplashScreen::finishedLoading();
}
void CollectionList::initialize(PlaylistCollection *collection)
{
if(m_list)
return;
// We have to delay initialization here because dynamic_cast or comparing to
// the collection instance won't work in the PlaylistBox::Item initialization
// won't work until the CollectionList is fully constructed.
m_list = new CollectionList(collection);
m_list->setName(i18n("Collection List"));
collection->setupPlaylist(m_list, "folder-sound");
}
......@@ -206,6 +217,8 @@ void CollectionList::clear()
void CollectionList::slotCheckCache()
{
loadCachedItems();
PlaylistItemList invalidItems;
foreach(CollectionListItem *item, m_itemsDict) {
......
......@@ -140,6 +140,13 @@ signals:
void signalNewTag(const QString &, unsigned);
void signalRemovedTag(const QString &, unsigned);
public slots:
/**
* Loads the CollectionListItems from the Cache. Should be called after program
* initialization.
*/
void loadCachedItems();
private:
/**
* Just the size of the above enum to keep from hard coding it in several
......
......@@ -201,7 +201,9 @@ void CoverInfo::applyCoverToWholeAlbum(bool overwriteExistingCovers) const
coverKey CoverInfo::coverId() const
{
hasCover(); // Force check for cover.
if(m_coverKey == CoverManager::NoMatch)
m_coverKey = CoverManager::idForTrack(m_file.absFilePath());
return m_coverKey;
}
......
......@@ -93,7 +93,8 @@ JuK::JuK(QWidget *parent) :
setupSystemTray();
setupGlobalAccels();
SplashScreen::finishedLoading();
// slotCheckCache loads the cached entries first to populate the collection list
QTimer::singleShot(0, CollectionList::instance(), SLOT(slotCheckCache()));
QTimer::singleShot(0, this, SLOT(slotProcessArgs()));
......
......@@ -4,6 +4,7 @@ Type=Application
Exec=juk -caption "%c" %i
Icon=juk
X-DocPath=juk/index.html
X-DBUS-StartupType=Unique
Comment=
Terminal=false
Name=JuK
......
......@@ -42,6 +42,41 @@ static const char nathan[] = I18N_NOOP("Album cover manager");
static const char pascal[] = I18N_NOOP("Gimper of splash screen");
static const char laurent[] = I18N_NOOP("Porting to KDE 4 when no one else was around");
/**
* Loading from the cache can take forever, so subclass KUniqueApplication to use a quicker
* newInstance() function.
*/
class JuKApplication : public KUniqueApplication
{
public:
JuKApplication() : KUniqueApplication(), m_juk(0)
{
}
virtual ~JuKApplication()
{
delete m_juk;
m_juk = 0;
}
// Reimplementation
virtual int newInstance()
{
m_juk = new JuK;
KConfigGroup config(KGlobal::config(), "Settings");
if(!config.readEntry("StartDocked", false))
m_juk->show();
// Some single shots will allow startup to continue at this point so we can
// return.
return 0;
}
private:
JuK *m_juk;
};
int main(int argc, char *argv[])
{
KAboutData aboutData("juk", 0, ki18n("JuK"),
......@@ -74,30 +109,16 @@ int main(int argc, char *argv[])
KUniqueApplication::addCmdLineOptions();
KUniqueApplication a;
JuKApplication a;
// If this flag gets set then JuK will quit if you click the cover on the track
// announcement popup when JuK is only in the system tray (the systray has no widget).
a.setQuitOnLastWindowClosed(false);
// Here we do some DCOP locking of sorts to prevent incoming DCOP calls
// before JuK has finished its initialization.
#ifdef __GNUC__
#warning "kde4: port it"
#endif
//a.dcopClient()->suspend();
JuK *juk = new JuK;
//a.dcopClient()->resume();
bool startDocked;
KConfigGroup config(KGlobal::config(), "Settings");
startDocked = config.readEntry("StartDocked", false);
// Create the main window and such
if(!startDocked)
juk->show();
a.start();
return a.exec();
}
......
......@@ -129,7 +129,6 @@ PlaylistBox::PlaylistBox(QWidget *parent, Q3WidgetStack *playlistStack) :
#endif
CollectionList::initialize(this);
Cache::loadPlaylists(this);
viewModeAction->setCurrentItem(m_viewModeIndex);
m_viewModes[m_viewModeIndex]->setShown(true);
......@@ -160,6 +159,7 @@ PlaylistBox::PlaylistBox(QWidget *parent, Q3WidgetStack *playlistStack) :
connect(CollectionList::instance(), SIGNAL(signalRemovedTag(const QString &, unsigned)),
this, SLOT(slotRemoveItem(const QString &, unsigned)));
QTimer::singleShot(0, this, SLOT(slotLoadCachedPlaylists()));
QTimer::singleShot(0, object(), SLOT(slotScanFolders()));
enableDirWatch(true);
......@@ -703,6 +703,12 @@ void PlaylistBox::setupUpcomingPlaylist()
action<KToggleAction>("showUpcoming")->setChecked(enable);
}
void PlaylistBox::slotLoadCachedPlaylists()
{
Cache::loadPlaylists(this);
emit startupComplete();
}
////////////////////////////////////////////////////////////////////////////////
// PlaylistBox::Item protected methods
////////////////////////////////////////////////////////////////////////////////
......
......@@ -78,6 +78,7 @@ protected:
signals:
void signalPlaylistDestroyed(Playlist *);
void startupComplete(); ///< Emitted after playlists are loaded.
private:
void readConfig();
......@@ -119,6 +120,9 @@ private slots:
void slotAddItem(const QString &tag, unsigned column);
void slotRemoveItem(const QString &tag, unsigned column);
// Used to load the playlists after GUI setup.
void slotLoadCachedPlaylists();
private:
KMenu *m_contextMenu;
QHash<Playlist *, Item*> m_playlistDict;
......
......@@ -371,9 +371,9 @@ int PlaylistItem::compare(const PlaylistItem *firstItem, const PlaylistItem *sec
return 0;
break;
case CoverColumn:
if(firstItem->d->fileHandle.coverInfo()->hasCover() == secondItem->d->fileHandle.coverInfo()->hasCover())
if(firstItem->d->fileHandle.coverInfo()->coverId() == secondItem->d->fileHandle.coverInfo()->coverId())
return 0;
else if (firstItem->d->fileHandle.coverInfo()->hasCover())
else if (firstItem->d->fileHandle.coverInfo()->coverId() != CoverManager::NoMatch)
return -1;
else
return 1;
......
......@@ -147,6 +147,10 @@ void PlaylistSplitter::setupLayout()
{
setOpaqueResize(false);
// Disable the GUI until startup is complete (as indicated by PlaylistBox)
setEnabled(false);
// Create a splitter to go between the playlists and the editor.
QSplitter *editorSplitter = new QSplitter(Qt::Vertical, this);
......@@ -180,6 +184,7 @@ void PlaylistSplitter::setupLayout()
this, SLOT(slotPlaylistSelectionChanged()));
connect(m_playlistBox, SIGNAL(signalPlaylistDestroyed(Playlist *)),
m_editor, SLOT(slotPlaylistDestroyed(Playlist *)));
connect(m_playlistBox, SIGNAL(startupComplete()), SLOT(slotEnable()));
insertWidget(0, m_playlistBox);
......@@ -258,6 +263,11 @@ void PlaylistSplitter::slotPlaylistChanged(QWidget *w)
m_newVisible = 0;
}
void PlaylistSplitter::slotEnable()
{
setEnabled(true); // Ready to go.
}
#include "playlistsplitter.moc"
// vim: set et sw=4 tw=0 sta:
......@@ -50,6 +50,7 @@ public:
public slots:
virtual void setFocus();
virtual void slotFocusCurrentPlaylist();
void slotEnable();
private:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment