summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorunK <electricityispower@gmail.com>2008-10-27 20:35:02 +0100
committerunK <electricityispower@gmail.com>2008-10-27 20:35:02 +0100
commitbeee0bc9d3aa66a7a22ce7de60e150c05d9e8db8 (patch)
tree8473e5013bd3cf127082ac38e29fa4aee6928cfa /src
parente1202f2dfe868253ed0b42ad0742272c25161f12 (diff)
add support for browsing local filesystem
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am9
-rw-r--r--src/browser.cpp211
-rw-r--r--src/browser.h34
-rw-r--r--src/help.cpp6
-rw-r--r--src/helpers.cpp113
-rw-r--r--src/helpers.h3
-rw-r--r--src/mpdpp.cpp11
-rw-r--r--src/mpdpp.h3
-rw-r--r--src/ncmpcpp.cpp101
-rw-r--r--src/settings.cpp1
-rw-r--r--src/settings.h1
-rw-r--r--src/song.cpp8
-rw-r--r--src/status_checker.cpp1
-rw-r--r--src/tag_editor.cpp15
-rw-r--r--src/tag_editor.h1
15 files changed, 347 insertions, 171 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index cc102a1e..0fedb998 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,12 +1,13 @@
bin_PROGRAMS = ncmpcpp
-ncmpcpp_SOURCES = color_parser.cpp help.cpp helpers.cpp libmpdclient.c \
- lyrics.cpp menu.cpp misc.cpp mpdpp.cpp ncmpcpp.cpp scrollpad.cpp search_engine.cpp \
- settings.cpp song.cpp status_checker.cpp str_pool.c tag_editor.cpp window.cpp
+ncmpcpp_SOURCES = browser.cpp color_parser.cpp help.cpp helpers.cpp \
+ libmpdclient.c lyrics.cpp menu.cpp misc.cpp mpdpp.cpp ncmpcpp.cpp scrollpad.cpp \
+ search_engine.cpp settings.cpp song.cpp status_checker.cpp str_pool.c tag_editor.cpp \
+ window.cpp
# set the include path found by configure
INCLUDES= $(all_includes)
# the library search path.
ncmpcpp_LDFLAGS = $(all_libraries)
-noinst_HEADERS = help.h helpers.h lyrics.h menu.h mpdpp.h scrollpad.h \
+noinst_HEADERS = browser.h help.h helpers.h lyrics.h menu.h mpdpp.h scrollpad.h \
search_engine.h settings.h song.h status_checker.h tag_editor.h window.h
diff --git a/src/browser.cpp b/src/browser.cpp
new file mode 100644
index 00000000..6aee9cd1
--- /dev/null
+++ b/src/browser.cpp
@@ -0,0 +1,211 @@
+/***************************************************************************
+ * Copyright (C) 2008 by Andrzej Rybczak *
+ * electricityispower@gmail.com *
+ * *
+ * 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. *
+ * *
+ * This program 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, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#include <dirent.h>
+#include <sys/stat.h>
+#include <algorithm>
+
+#include "browser.h"
+#include "helpers.h"
+#include "settings.h"
+#ifdef HAVE_TAGLIB_H
+# include "tag_editor.h"
+#endif // HAVE_TAGLIB_H
+
+extern MPDConnection *Mpd;
+
+extern ncmpcpp_config Config;
+
+extern Menu<Song> *mPlaylist;
+extern Menu<Item> *mBrowser;
+
+extern NcmpcppScreen current_screen;
+
+extern string browsed_dir;
+
+extern int browsed_dir_scroll_begin;
+
+namespace
+{
+ const string supported_extensions[] = { "wma", "asf", "rm", "mp1", "mp2", "mp3", "mp4", "m4a", "flac", "ogg", "wav", "au", "aiff", "aif", "ac3", "aac", "mpc", "it", "mod", "s3m", "xm", "wv", "." };
+
+ bool hasSupportedExtension(const string &file)
+ {
+ unsigned int last_dot = file.find_last_of(".");
+ if (last_dot > file.length())
+ return false;
+
+ string ext = file.substr(last_dot+1);
+ for (int i = 0; supported_extensions[i] != "."; i++)
+ if (ext == supported_extensions[i])
+ return true;
+
+ return false;
+ }
+
+ void GetLocalDirectory(const string &dir, ItemList &v)
+ {
+ dirent **list;
+ int n = scandir(dir.c_str(), &list, NULL, alphasort);
+ if (n < 2)
+ {
+ delete list;
+ return;
+ }
+ struct stat file_stat;
+ string full_path;
+ for (int i = 2; i < n; i++)
+ {
+ Item new_item;
+ full_path = dir;
+ if (dir != "/")
+ full_path += "/";
+ full_path += list[i]->d_name;
+ stat(full_path.c_str(), &file_stat);
+ if (S_ISDIR(file_stat.st_mode))
+ {
+ new_item.type = itDirectory;
+ new_item.name = full_path;
+ v.push_back(new_item);
+ }
+ else if (hasSupportedExtension(list[i]->d_name))
+ {
+ new_item.type = itSong;
+ mpd_Song *s = mpd_newSong();
+ s->file = str_pool_get(full_path.c_str());
+# ifdef HAVE_TAGLIB_H
+ ReadTagsFromFile(s);
+# endif // HAVE_TAGLIB_H
+ new_item.song = new Song(s);
+ v.push_back(new_item);
+ }
+ delete list[i];
+ }
+ delete list;
+ }
+}
+
+void UpdateItemList(Menu<Item> *menu)
+{
+ bool bold = 0;
+ for (int i = 0; i < menu->Size(); i++)
+ {
+ if (menu->at(i).type == itSong)
+ {
+ for (int j = 0; j < mPlaylist->Size(); j++)
+ {
+ if (mPlaylist->at(j).GetHash() == menu->at(i).song->GetHash())
+ {
+ bold = 1;
+ break;
+ }
+ }
+ menu->BoldOption(i, bold);
+ bold = 0;
+ }
+ }
+ menu->Refresh();
+}
+
+string DisplayItem(const Item &item, void *, const Menu<Item> *menu)
+{
+ switch (item.type)
+ {
+ case itDirectory:
+ {
+ if (item.song)
+ return "[..]";
+ int slash = item.name.find_last_of("/");
+ return "[" + (slash != string::npos ? item.name.substr(slash+1) : item.name) + "]";
+ }
+ case itSong:
+ // I know casting that way is ugly etc., but it works.
+ return DisplaySong(*item.song, &Config.song_list_format, (const Menu<Song> *)menu);
+ case itPlaylist:
+ return Config.browser_playlist_prefix + item.name;
+ default:
+ return "";
+ }
+}
+
+void GetDirectory(string dir, string subdir)
+{
+ if (dir.empty())
+ dir = "/";
+
+ int highlightme = -1;
+ browsed_dir_scroll_begin = 0;
+ if (browsed_dir != dir)
+ mBrowser->Reset();
+ browsed_dir = dir;
+ mBrowser->Clear(0);
+
+ if (dir != "/")
+ {
+ Item parent;
+ int slash = dir.find_last_of("/");
+ parent.song = (Song *) 1; // in that way we assume that's really parent dir
+ parent.name = slash != string::npos ? dir.substr(0, slash) : "/";
+ parent.type = itDirectory;
+ mBrowser->AddOption(parent);
+ }
+
+ ItemList list;
+ Config.local_browser ? GetLocalDirectory(dir, list) : Mpd->GetDirectory(dir, list);
+ sort(list.begin(), list.end(), CaseInsensitiveSorting());
+
+ for (ItemList::iterator it = list.begin(); it != list.end(); it++)
+ {
+ switch (it->type)
+ {
+ case itPlaylist:
+ {
+ mBrowser->AddOption(*it);
+ break;
+ }
+ case itDirectory:
+ {
+ if (it->name == subdir)
+ highlightme = mBrowser->Size();
+ mBrowser->AddOption(*it);
+ break;
+ }
+ case itSong:
+ {
+ bool bold = 0;
+ for (int i = 0; i < mPlaylist->Size(); i++)
+ {
+ if (mPlaylist->at(i).GetHash() == it->song->GetHash())
+ {
+ bold = 1;
+ break;
+ }
+ }
+ mBrowser->AddOption(*it, bold);
+ break;
+ }
+ }
+ }
+ mBrowser->Highlight(highlightme);
+
+ if (current_screen == csBrowser)
+ mBrowser->Hide();
+}
+
diff --git a/src/browser.h b/src/browser.h
new file mode 100644
index 00000000..68f92955
--- /dev/null
+++ b/src/browser.h
@@ -0,0 +1,34 @@
+/***************************************************************************
+ * Copyright (C) 2008 by Andrzej Rybczak *
+ * electricityispower@gmail.com *
+ * *
+ * 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. *
+ * *
+ * This program 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, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#ifndef HAVE_BROWSER_H
+#define HAVE_BROWSER_H
+
+#include "mpdpp.h"
+#include "ncmpcpp.h"
+
+void UpdateItemList(Menu<Item> *);
+
+string DisplayItem(const Item &, void *, const Menu<Item> *);
+
+void GetDirectory(string, string = "/");
+
+#endif
+
diff --git a/src/help.cpp b/src/help.cpp
index f67d589d..ae6ce052 100644
--- a/src/help.cpp
+++ b/src/help.cpp
@@ -18,9 +18,13 @@
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
+#include "mpdpp.h"
+
#include "help.h"
#include "settings.h"
+extern MPDConnection *Mpd;
+
extern ncmpcpp_keys Key;
namespace
@@ -165,6 +169,8 @@ string GetKeybindings()
result += " [.b]Keys - Browse screen\n -----------------------------------------[/b]\n";
result += DisplayKeys(Key.Enter) + "Enter directory/Add item to playlist and play\n";
result += DisplayKeys(Key.Space) + "Add item to playlist\n";
+ if (Mpd->GetHostname()[0] == '/') // are we connected to unix socket?
+ result += DisplayKeys(Key.SwitchTagTypeList) + "Browse MPD database/local filesystem\n";
result += DisplayKeys(Key.GoToParentDir) + "Go to parent directory\n";
result += DisplayKeys(Key.Delete) + "Delete playlist\n\n\n";
diff --git a/src/helpers.cpp b/src/helpers.cpp
index 485e4f94..2fe4e962 100644
--- a/src/helpers.cpp
+++ b/src/helpers.cpp
@@ -35,12 +35,9 @@ extern Window *wFooter;
extern NcmpcppScreen current_screen;
extern int lock_statusbar_delay;
-extern int browsed_dir_scroll_begin;
extern time_t time_of_statusbar_lock;
-extern string browsed_dir;
-
extern bool messages_allowed;
extern bool block_progressbar_update;
extern bool block_statusbar_update;
@@ -220,28 +217,6 @@ bool CaseInsensitiveSorting::operator()(const Item &a, const Item &b)
return a.type < b.type;
}
-void UpdateItemList(Menu<Item> *menu)
-{
- bool bold = 0;
- for (int i = 0; i < menu->Size(); i++)
- {
- if (menu->at(i).type == itSong)
- {
- for (int j = 0; j < mPlaylist->Size(); j++)
- {
- if (mPlaylist->at(j).GetHash() == menu->at(i).song->GetHash())
- {
- bold = 1;
- break;
- }
- }
- menu->BoldOption(i, bold);
- bold = 0;
- }
- }
- menu->Refresh();
-}
-
void UpdateSongList(Menu<Song> *menu)
{
bool bold = 0;
@@ -395,27 +370,6 @@ string DisplayStringPair(const StringPair &pair, void *, const Menu<StringPair>
return pair.first;
}
-string DisplayItem(const Item &item, void *, const Menu<Item> *menu)
-{
- switch (item.type)
- {
- case itDirectory:
- {
- if (item.song)
- return "[..]";
- int slash = item.name.find_last_of("/");
- return "[" + (slash != string::npos ? item.name.substr(slash+1) : item.name) + "]";
- }
- case itSong:
- // I know casting that way is ugly etc., but it works.
- return DisplaySong(*item.song, &Config.song_list_format, (const Menu<Song> *)menu);
- case itPlaylist:
- return Config.browser_playlist_prefix + item.name;
- default:
- return "";
- }
-}
-
string DisplayColumns(string song_template)
{
vector<string> cols;
@@ -577,7 +531,11 @@ string DisplaySongInColumns(const Song &s, void *s_template, const Menu<Song> *)
v = TO_WSTRING(Window::OmitBBCodes(ss)).substr(0, width-1);
for (int i = v.length(); i < width; i++, v += space) { }
if (!color.empty())
- result += open_col + color + close_col;
+ {
+ result += open_col;
+ result += color;
+ result += close_col;
+ }
result += v;
if (!color.empty())
result += close_col2;
@@ -913,64 +871,3 @@ void ShowMessage(const string &message, int delay)
}
}
-void GetDirectory(string dir, string subdir)
-{
- int highlightme = -1;
- browsed_dir_scroll_begin = 0;
- if (browsed_dir != dir)
- mBrowser->Reset();
- browsed_dir = dir;
- mBrowser->Clear(0);
-
- if (dir != "/")
- {
- Item parent;
- int slash = dir.find_last_of("/");
- parent.song = (Song *) 1; // in that way we assume that's really parent dir
- parent.name = slash != string::npos ? dir.substr(0, slash) : "/";
- parent.type = itDirectory;
- mBrowser->AddOption(parent);
- }
-
- ItemList list;
- Mpd->GetDirectory(dir, list);
- sort(list.begin(), list.end(), CaseInsensitiveSorting());
-
- for (ItemList::iterator it = list.begin(); it != list.end(); it++)
- {
- switch (it->type)
- {
- case itPlaylist:
- {
- mBrowser->AddOption(*it);
- break;
- }
- case itDirectory:
- {
- if (it->name == subdir)
- highlightme = mBrowser->Size();
- mBrowser->AddOption(*it);
- break;
- }
- case itSong:
- {
- bool bold = 0;
- for (int i = 0; i < mPlaylist->Size(); i++)
- {
- if (mPlaylist->at(i).GetHash() == it->song->GetHash())
- {
- bold = 1;
- break;
- }
- }
- mBrowser->AddOption(*it, bold);
- break;
- }
- }
- }
- mBrowser->Highlight(highlightme);
-
- if (current_screen == csBrowser)
- mBrowser->Hide();
-}
-
diff --git a/src/helpers.h b/src/helpers.h
index c5b51693..ce26fa7d 100644
--- a/src/helpers.h
+++ b/src/helpers.h
@@ -43,7 +43,6 @@ class CaseInsensitiveSorting
bool SortSongsByTrack(Song *, Song *);
-void UpdateItemList(Menu<Item> *);
void UpdateSongList(Menu<Song> *);
bool Keypressed(int, const int *);
@@ -55,13 +54,11 @@ string IntoStr(mpd_TagItems);
string FindSharedDir(const string &, const string &);
string TotalPlaylistLength();
string DisplayStringPair(const StringPair &, void *, const Menu<StringPair> *);
-string DisplayItem(const Item &, void *, const Menu<Item> *);
string DisplayColumns(string);
string DisplaySongInColumns(const Song &, void *, const Menu<Song> *);
string DisplaySong(const Song &, void * = &Config.song_list_format, const Menu<Song> * = NULL);
string GetInfo(Song &);
void ShowMessage(const string &, int = Config.message_delay_time);
-void GetDirectory(string, string = "/");
#endif
diff --git a/src/mpdpp.cpp b/src/mpdpp.cpp
index 340c4931..a743ce03 100644
--- a/src/mpdpp.cpp
+++ b/src/mpdpp.cpp
@@ -22,7 +22,14 @@
const string playlist_max_message = "playlist is at the max size";
-MPDConnection::MPDConnection() : isConnected(0), itsErrorCode(0), itsMaxPlaylistLength(-1), MPD_HOST("localhost"), MPD_PORT(6600), MPD_TIMEOUT(15), itsUpdater(0), itsErrorHandler(0)
+MPDConnection::MPDConnection() : isConnected(0),
+ itsErrorCode(0),
+ itsMaxPlaylistLength(-1),
+ MPD_HOST("localhost"),
+ MPD_PORT(6600),
+ MPD_TIMEOUT(15),
+ itsUpdater(0),
+ itsErrorHandler(0)
{
itsConnection = 0;
itsCurrentStats = 0;
@@ -467,7 +474,7 @@ int MPDConnection::AddSong(const string &path)
int MPDConnection::AddSong(const Song &s)
{
- return !s.Empty() ? AddSong(s.GetFile()) : -1;
+ return !s.Empty() ? (s.IsFromDB() ? AddSong(s.GetFile()) : AddSong("file://" + s.GetFile())) : -1;
}
void MPDConnection::QueueAddSong(const string &path)
diff --git a/src/mpdpp.h b/src/mpdpp.h
index 58412175..35767bcc 100644
--- a/src/mpdpp.h
+++ b/src/mpdpp.h
@@ -82,6 +82,9 @@ class MPDConnection
bool Connected() const;
void Disconnect();
+ const string & GetHostname() { return MPD_HOST; }
+ int GetPort() { return MPD_PORT; }
+
void SetHostname(const string &);
void SetPort(int port) { MPD_PORT = port; }
void SetTimeout(int timeout) { MPD_TIMEOUT = timeout; }
diff --git a/src/ncmpcpp.cpp b/src/ncmpcpp.cpp
index e361cbf4..dafda9e9 100644
--- a/src/ncmpcpp.cpp
+++ b/src/ncmpcpp.cpp
@@ -28,6 +28,7 @@
#include "mpdpp.h"
#include "ncmpcpp.h"
+#include "browser.h"
#include "help.h"
#include "helpers.h"
#include "lyrics.h"
@@ -923,7 +924,7 @@ int main(int argc, char *argv[])
if (wCurrent == mBrowser && browsed_dir != "/")
{
mBrowser->Reset();
- goto GO_TO_PARENT_DIR;
+ goto ENTER_BROWSER_SCREEN;
}
}
else if (Keypressed(input, Key.Enter))
@@ -938,7 +939,7 @@ int main(int argc, char *argv[])
}
case csBrowser:
{
- GO_TO_PARENT_DIR:
+ ENTER_BROWSER_SCREEN:
const Item &item = mBrowser->Current();
switch (item.type)
@@ -1135,7 +1136,12 @@ int main(int argc, char *argv[])
mSearcher->Current().second = s;
}
else
- mPlaylist->Current() = s;
+ {
+ if (wPrev == mPlaylist)
+ mPlaylist->Current() = s;
+ else if (wPrev == mBrowser)
+ *mBrowser->Current().song = s;
+ }
}
else
ShowMessage("Error writing tags!");
@@ -2025,7 +2031,8 @@ int main(int argc, char *argv[])
{
Mpd->DeletePlaylist(name);
ShowMessage("Playlist " + name + " deleted!");
- GetDirectory("/");
+ if (!Config.local_browser)
+ GetDirectory("/");
}
else
ShowMessage("Aborted!");
@@ -2122,7 +2129,7 @@ int main(int argc, char *argv[])
UnlockStatusbar();
}
}
- if (browsed_dir == "/" && !mBrowser->Empty())
+ if (!Config.local_browser && browsed_dir == "/" && !mBrowser->Empty())
GetDirectory(browsed_dir);
}
else if (Keypressed(input, Key.Stop))
@@ -2653,27 +2660,6 @@ int main(int argc, char *argv[])
ShowMessage("Cannot rename '" + full_old_dir + "' to '" + full_new_dir + "'!");
}
}
- // blah, this key is already reserved for TagEditor. I'll merge this to its screen later.
- /*else if (wCurrent == mBrowser && mBrowser->Current().type == itSong)
- {
- string old_name = mBrowser->Current().song->GetFile();
- LockStatusbar();
- wFooter->WriteXY(0, Config.statusbar_visibility, "[.b]Filename:[/b] ", 1);
- string new_name = wFooter->GetString(old_name);
- UnlockStatusbar();
- if (!new_name.empty() && new_name != old_name)
- {
- string full_old_name = Config.mpd_music_dir + old_name;
- string full_new_name = Config.mpd_music_dir + new_name;
- if (rename(full_old_name.c_str(), full_new_name.c_str()) == 0)
- {
- Mpd->UpdateDirectory(FindSharedDir(old_name, new_name));
- ShowMessage("'" + old_name + "' renamed to '" + new_name + "'");
- }
- else
- ShowMessage("Cannot rename '" + old_name + "' to '" + new_name + "'!");
- }
- }*/
else if (wCurrent == mPlaylistList || (wCurrent == mBrowser && mBrowser->Current().type == itPlaylist))
{
string old_name = wCurrent == mPlaylistList ? mPlaylistList->GetOption() : mBrowser->Current().name;
@@ -2685,7 +2671,8 @@ int main(int argc, char *argv[])
{
Mpd->Rename(old_name, new_name);
ShowMessage("Playlist '" + old_name + "' renamed to '" + new_name + "'");
- GetDirectory("/");
+ if (!Config.local_browser)
+ GetDirectory("/");
mPlaylistList->Clear(0);
}
}
@@ -2724,6 +2711,8 @@ int main(int argc, char *argv[])
if (s->GetDirectory() == EMPTY_TAG) // for streams
continue;
+ Config.local_browser = !s->IsFromDB();
+
string option = DisplaySong(*s, &Config.song_list_format, mPlaylist);
GetDirectory(s->GetDirectory());
for (int i = 0; i < mBrowser->Size(); i++)
@@ -2949,7 +2938,7 @@ int main(int argc, char *argv[])
if (id != mDialog->Size()-1)
{
// refresh playlist's lists
- if (browsed_dir == "/")
+ if (!Config.local_browser && browsed_dir == "/")
GetDirectory("/");
mPlaylistList->Clear(0); // make playlist editor update itself
}
@@ -3097,31 +3086,43 @@ int main(int argc, char *argv[])
Config.ncmpc_like_songs_adding = !Config.ncmpc_like_songs_adding;
ShowMessage("Add mode: " + string(Config.ncmpc_like_songs_adding ? "Add item to playlist, remove if already added" : "Always add item to playlist"));
}
- else if (Keypressed(input, Key.SwitchTagTypeList) && wCurrent == mLibArtists)
+ else if (Keypressed(input, Key.SwitchTagTypeList))
{
- LockStatusbar();
- wFooter->WriteXY(0, Config.statusbar_visibility, "Tag type ? [[.b]a[/b]rtist/[.b]y[/b]ear/[.b]g[/b]enre/[.b]c[/b]omposer/[.b]p[/b]erformer] ", 1);
- int item;
- curs_set(1);
- do
+ if (wCurrent == mBrowser && Mpd->GetHostname()[0] == '/')
{
- TraceMpdStatus();
- wFooter->ReadKey(item);
+ Config.local_browser = !Config.local_browser;
+ ShowMessage("Browse mode: " + string(Config.local_browser ? "Local filesystem" : "MPD music dir"));
+ browsed_dir = Config.local_browser ? home_folder : "/";
+ mBrowser->Reset();
+ GetDirectory(browsed_dir);
+ redraw_header = 1;
}
- while (item != 'a' && item != 'y' && item != 'g' && item != 'c' && item != 'p');
- curs_set(0);
- UnlockStatusbar();
- mpd_TagItems new_tagitem = IntoTagItem(item);
- if (new_tagitem != Config.media_lib_primary_tag)
- {
- Config.media_lib_primary_tag = new_tagitem;
- string item_type = IntoStr(Config.media_lib_primary_tag);
- mLibArtists->SetTitle(item_type + "s");
- mLibArtists->Reset();
- mLibArtists->Clear(0);
- mLibArtists->Display();
- ToLower(item_type);
- ShowMessage("Switched to list of " + item_type + " tag");
+ else if (wCurrent == mLibArtists)
+ {
+ LockStatusbar();
+ wFooter->WriteXY(0, Config.statusbar_visibility, "Tag type ? [[.b]a[/b]rtist/[.b]y[/b]ear/[.b]g[/b]enre/[.b]c[/b]omposer/[.b]p[/b]erformer] ", 1);
+ int item;
+ curs_set(1);
+ do
+ {
+ TraceMpdStatus();
+ wFooter->ReadKey(item);
+ }
+ while (item != 'a' && item != 'y' && item != 'g' && item != 'c' && item != 'p');
+ curs_set(0);
+ UnlockStatusbar();
+ mpd_TagItems new_tagitem = IntoTagItem(item);
+ if (new_tagitem != Config.media_lib_primary_tag)
+ {
+ Config.media_lib_primary_tag = new_tagitem;
+ string item_type = IntoStr(Config.media_lib_primary_tag);
+ mLibArtists->SetTitle(item_type + "s");
+ mLibArtists->Reset();
+ mLibArtists->Clear(0);
+ mLibArtists->Display();
+ ToLower(item_type);
+ ShowMessage("Switched to list of " + item_type + " tag");
+ }
}
}
else if (Keypressed(input, Key.SongInfo))
diff --git a/src/settings.cpp b/src/settings.cpp
index 3ea23e00..d0d59166 100644
--- a/src/settings.cpp
+++ b/src/settings.cpp
@@ -202,6 +202,7 @@ void DefaultConfiguration(ncmpcpp_config &conf)
conf.albums_in_tag_editor = false;
conf.incremental_seeking = true;
conf.now_playing_lyrics = false;
+ conf.local_browser = false;
conf.set_window_title = true;
conf.mpd_connection_timeout = 15;
conf.crossfade_time = 5;
diff --git a/src/settings.h b/src/settings.h
index dd6b646d..1dadf10e 100644
--- a/src/settings.h
+++ b/src/settings.h
@@ -142,6 +142,7 @@ struct ncmpcpp_config
bool albums_in_tag_editor;
bool incremental_seeking;
bool now_playing_lyrics;
+ bool local_browser;
int mpd_connection_timeout;
int crossfade_time;
diff --git a/src/song.cpp b/src/song.cpp
index f316d1f5..fb8e3b28 100644
--- a/src/song.cpp
+++ b/src/song.cpp
@@ -61,11 +61,11 @@ Song::Song(mpd_Song *s, bool copy_ptr) : itsSong(s),
isStream = 1;
// generate pseudo-hash
- for (int i = 0; i < strlen(itsSong->file); i++)
+ for (int i = 0; i < itsFile.length(); i++)
{
- itsHash += itsSong->file[i];
- if (i%2)
- itsHash *= itsSong->file[i];
+ itsHash += itsFile[i];
+ if (i%3)
+ itsHash *= itsFile[i];
}
}
diff --git a/src/status_checker.cpp b/src/status_checker.cpp
index f1d31768..88ae7bfb 100644
--- a/src/status_checker.cpp
+++ b/src/status_checker.cpp
@@ -18,6 +18,7 @@
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
+#include "browser.h"
#include "helpers.h"
#include "search_engine.h"
#include "settings.h"
diff --git a/src/tag_editor.cpp b/src/tag_editor.cpp
index 72caf6a6..ca492b3e 100644
--- a/src/tag_editor.cpp
+++ b/src/tag_editor.cpp
@@ -129,6 +129,21 @@ string DisplayTag(const Song &s, void *data, const Menu<Song> *)
}
}
+void ReadTagsFromFile(mpd_Song *s)
+{
+ TagLib::FileRef f(s->file);
+ if (f.isNull())
+ return;
+ s->artist = !f.tag()->artist().isEmpty() ? str_pool_get(f.tag()->artist().to8Bit(UNICODE).c_str()) : 0;
+ s->title = !f.tag()->title().isEmpty() ? str_pool_get(f.tag()->title().to8Bit(UNICODE).c_str()) : 0;
+ s->album = !f.tag()->album().isEmpty() ? str_pool_get(f.tag()->album().to8Bit(UNICODE).c_str()) : 0;
+ s->track = f.tag()->track() ? str_pool_get(IntoStr(f.tag()->track()).c_str()) : 0;
+ s->date = f.tag()->year() ? str_pool_get(IntoStr(f.tag()->year()).c_str()) : 0;
+ s->genre = !f.tag()->genre().isEmpty() ? str_pool_get(f.tag()->genre().to8Bit(UNICODE).c_str()) : 0;
+ s->comment = !f.tag()->comment().isEmpty() ? str_pool_get(f.tag()->comment().to8Bit(UNICODE).c_str()) : 0;
+ s->time = f.audioProperties()->length();
+}
+
bool GetSongTags(Song &s)
{
string path_to_file;
diff --git a/src/tag_editor.h b/src/tag_editor.h
index 1ce52743..bb22e33d 100644
--- a/src/tag_editor.h
+++ b/src/tag_editor.h
@@ -40,6 +40,7 @@ string DisplayTag(const Song &, void *, const Menu<Song> *);
SongSetFunction IntoSetFunction(mpd_TagItems);
+void ReadTagsFromFile(mpd_Song *);
bool GetSongTags(Song &);
bool WriteTags(Song &);