remove color parser / update Window, Scrollpad class and related stuff

This commit is contained in:
Andrzej Rybczak
2008-12-09 16:40:04 +01:00
parent 51e59b04b9
commit c03bcbe44b
16 changed files with 862 additions and 860 deletions

View File

@@ -1,8 +1,7 @@
bin_PROGRAMS = ncmpcpp
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
ncmpcpp_SOURCES = browser.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)

View File

@@ -88,133 +88,129 @@ namespace
}
}
string GetKeybindings()
void GetKeybindings(Scrollpad &help)
{
string result;
help << " " << fmtBold << "Keys - Movement\n -----------------------------------------\n" << fmtBoldEnd;
help << DisplayKeys(Key.Up) << "Move Cursor up\n";
help << DisplayKeys(Key.Down) << "Move Cursor down\n";
help << DisplayKeys(Key.PageUp) << "Page up\n";
help << DisplayKeys(Key.PageDown) << "Page down\n";
help << DisplayKeys(Key.Home) << "Home\n";
help << DisplayKeys(Key.End) << "End\n\n";
result += " [.b]Keys - Movement\n -----------------------------------------[/b]\n";
result += DisplayKeys(Key.Up) + "Move Cursor up\n";
result += DisplayKeys(Key.Down) + "Move Cursor down\n";
result += DisplayKeys(Key.PageUp) + "Page up\n";
result += DisplayKeys(Key.PageDown) + "Page down\n";
result += DisplayKeys(Key.Home) + "Home\n";
result += DisplayKeys(Key.End) + "End\n\n";
result += DisplayKeys(Key.ScreenSwitcher) + "Switch between playlist and browser\n";
result += DisplayKeys(Key.Help) + "Help screen\n";
result += DisplayKeys(Key.Playlist) + "Playlist screen\n";
result += DisplayKeys(Key.Browser) + "Browse screen\n";
result += DisplayKeys(Key.SearchEngine) + "Search engine\n";
result += DisplayKeys(Key.MediaLibrary) + "Media library\n";
result += DisplayKeys(Key.PlaylistEditor) + "Playlist editor\n";
help << DisplayKeys(Key.ScreenSwitcher) << "Switch between playlist and browser\n";
help << DisplayKeys(Key.Help) << "Help screen\n";
help << DisplayKeys(Key.Playlist) << "Playlist screen\n";
help << DisplayKeys(Key.Browser) << "Browse screen\n";
help << DisplayKeys(Key.SearchEngine) << "Search engine\n";
help << DisplayKeys(Key.MediaLibrary) << "Media library\n";
help << DisplayKeys(Key.PlaylistEditor) << "Playlist editor\n";
# ifdef HAVE_TAGLIB_H
result += DisplayKeys(Key.TagEditor) + "Tag editor\n\n\n";
help << DisplayKeys(Key.TagEditor) << "Tag editor\n\n\n";
# else
result += "\n\n";
help << "\n\n";
# endif // HAVE_TAGLIB_H
result += " [.b]Keys - Global\n -----------------------------------------[/b]\n";
result += DisplayKeys(Key.Stop) + "Stop\n";
result += DisplayKeys(Key.Pause) + "Pause\n";
result += DisplayKeys(Key.Next) + "Next track\n";
result += DisplayKeys(Key.Prev) + "Previous track\n";
result += DisplayKeys(Key.SeekForward) + "Seek forward\n";
result += DisplayKeys(Key.SeekBackward) + "Seek backward\n";
result += DisplayKeys(Key.VolumeDown) + "Decrease volume\n";
result += DisplayKeys(Key.VolumeUp) + "Increase volume\n\n";
help << " " << fmtBold << "Keys - Global\n -----------------------------------------\n" << fmtBoldEnd;
help << DisplayKeys(Key.Stop) << "Stop\n";
help << DisplayKeys(Key.Pause) << "Pause\n";
help << DisplayKeys(Key.Next) << "Next track\n";
help << DisplayKeys(Key.Prev) << "Previous track\n";
help << DisplayKeys(Key.SeekForward) << "Seek forward\n";
help << DisplayKeys(Key.SeekBackward) << "Seek backward\n";
help << DisplayKeys(Key.VolumeDown) << "Decrease volume\n";
help << DisplayKeys(Key.VolumeUp) << "Increase volume\n\n";
result += DisplayKeys(Key.ToggleSpaceMode) + "Toggle space mode (select/add)\n";
result += DisplayKeys(Key.ToggleAddMode) + "Toggle add mode\n";
result += DisplayKeys(Key.ReverseSelection) + "Reverse selection\n";
result += DisplayKeys(Key.DeselectAll) + "Deselect all items\n";
result += DisplayKeys(Key.AddSelected) + "Add selected items to playlist/m3u file\n\n";
help << DisplayKeys(Key.ToggleSpaceMode) << "Toggle space mode (select/add)\n";
help << DisplayKeys(Key.ToggleAddMode) << "Toggle add mode\n";
help << DisplayKeys(Key.ReverseSelection) << "Reverse selection\n";
help << DisplayKeys(Key.DeselectAll) << "Deselect all items\n";
help << DisplayKeys(Key.AddSelected) << "Add selected items to playlist/m3u file\n\n";
result += DisplayKeys(Key.ToggleRepeat) + "Toggle repeat mode\n";
result += DisplayKeys(Key.ToggleRepeatOne) + "Toggle \"repeat one\" mode\n";
result += DisplayKeys(Key.ToggleRandom) + "Toggle random mode\n";
result += DisplayKeys(Key.Shuffle) + "Shuffle playlist\n";
result += DisplayKeys(Key.ToggleCrossfade) + "Toggle crossfade mode\n";
result += DisplayKeys(Key.SetCrossfade) + "Set crossfade\n";
result += DisplayKeys(Key.UpdateDB) + "Start a music database update\n\n";
help << DisplayKeys(Key.ToggleRepeat) << "Toggle repeat mode\n";
help << DisplayKeys(Key.ToggleRepeatOne) << "Toggle \"repeat one\" mode\n";
help << DisplayKeys(Key.ToggleRandom) << "Toggle random mode\n";
help << DisplayKeys(Key.Shuffle) << "Shuffle playlist\n";
help << DisplayKeys(Key.ToggleCrossfade) << "Toggle crossfade mode\n";
help << DisplayKeys(Key.SetCrossfade) << "Set crossfade\n";
help << DisplayKeys(Key.UpdateDB) << "Start a music database update\n\n";
result += DisplayKeys(Key.FindForward) + "Forward find\n";
result += DisplayKeys(Key.FindBackward) + "Backward find\n";
result += DisplayKeys(Key.PrevFoundPosition) + "Go to previous found position\n";
result += DisplayKeys(Key.NextFoundPosition) + "Go to next found position\n";
result += DisplayKeys(Key.ToggleFindMode) + "Toggle find mode (normal/wrapped)\n";
result += DisplayKeys(Key.GoToContainingDir) + "Go to directory containing current item\n";
help << DisplayKeys(Key.FindForward) << "Forward find\n";
help << DisplayKeys(Key.FindBackward) << "Backward find\n";
help << DisplayKeys(Key.PrevFoundPosition) << "Go to previous found position\n";
help << DisplayKeys(Key.NextFoundPosition) << "Go to next found position\n";
help << DisplayKeys(Key.ToggleFindMode) << "Toggle find mode (normal/wrapped)\n";
help << DisplayKeys(Key.GoToContainingDir) << "Go to directory containing current item\n";
# ifdef HAVE_TAGLIB_H
result += DisplayKeys(Key.EditTags) + "Edit song's tags/playlist's name\n";
help << DisplayKeys(Key.EditTags) << "Edit song's tags/playlist's name\n";
# endif // HAVE_TAGLIB_H
result += DisplayKeys(Key.GoToPosition) + "Go to chosen position in current song\n";
result += DisplayKeys(Key.SongInfo) + "Show song's info\n";
help << DisplayKeys(Key.GoToPosition) << "Go to chosen position in current song\n";
help << DisplayKeys(Key.SongInfo) << "Show song's info\n";
# ifdef HAVE_CURL_CURL_H
result += DisplayKeys(Key.ArtistInfo) + "Show artist's info\n";
help << DisplayKeys(Key.ArtistInfo) << "Show artist's info\n";
# endif // HAVE_CURL_CURL_H
result += DisplayKeys(Key.Lyrics) + "Show/hide song's lyrics\n\n";
help << DisplayKeys(Key.Lyrics) << "Show/hide song's lyrics\n\n";
result += DisplayKeys(Key.Quit) + "Quit\n\n\n";
help << DisplayKeys(Key.Quit) << "Quit\n\n\n";
result += " [.b]Keys - Playlist screen\n -----------------------------------------[/b]\n";
result += DisplayKeys(Key.Enter) + "Play\n";
result += DisplayKeys(Key.Delete) + "Delete item/selected items from playlist\n";
result += DisplayKeys(Key.Clear) + "Clear playlist\n";
result += DisplayKeys(Key.Crop) + "Clear playlist but hold currently playing/selected items\n";
result += DisplayKeys(Key.MvSongUp) + "Move item/group of items up\n";
result += DisplayKeys(Key.MvSongDown) + "Move item/group of items down\n";
result += DisplayKeys(Key.Add) + "Add url/file/directory to playlist\n";
result += DisplayKeys(Key.SavePlaylist) + "Save playlist\n";
result += DisplayKeys(Key.GoToNowPlaying) + "Go to currently playing position\n";
result += DisplayKeys(Key.TogglePlaylistDisplayMode) + "Toggle playlist display mode\n";
result += DisplayKeys(Key.ToggleAutoCenter) + "Toggle auto center mode\n\n\n";
help << " " << fmtBold << "Keys - Playlist screen\n -----------------------------------------\n" << fmtBoldEnd;
help << DisplayKeys(Key.Enter) << "Play\n";
help << DisplayKeys(Key.Delete) << "Delete item/selected items from playlist\n";
help << DisplayKeys(Key.Clear) << "Clear playlist\n";
help << DisplayKeys(Key.Crop) << "Clear playlist but hold currently playing/selected items\n";
help << DisplayKeys(Key.MvSongUp) << "Move item/group of items up\n";
help << DisplayKeys(Key.MvSongDown) << "Move item/group of items down\n";
help << DisplayKeys(Key.Add) << "Add url/file/directory to playlist\n";
help << DisplayKeys(Key.SavePlaylist) << "Save playlist\n";
help << DisplayKeys(Key.GoToNowPlaying) << "Go to currently playing position\n";
help << DisplayKeys(Key.TogglePlaylistDisplayMode) << "Toggle playlist display mode\n";
help << DisplayKeys(Key.ToggleAutoCenter) << "Toggle auto center mode\n\n\n";
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";
help << " " << fmtBold << "Keys - Browse screen\n -----------------------------------------\n" << fmtBoldEnd;
help << DisplayKeys(Key.Enter) << "Enter directory/Add item to playlist and play\n";
help << 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";
help << DisplayKeys(Key.SwitchTagTypeList) << "Browse MPD database/local filesystem\n";
help << DisplayKeys(Key.GoToParentDir) << "Go to parent directory\n";
help << DisplayKeys(Key.Delete) << "Delete playlist\n\n\n";
result += " [.b]Keys - Search engine\n -----------------------------------------[/b]\n";
result += DisplayKeys(Key.Enter) + "Add item to playlist and play/change option\n";
result += DisplayKeys(Key.Space) + "Add item to playlist\n";
result += DisplayKeys(Key.StartSearching) + "Start searching immediately\n\n\n";
help << " " << fmtBold << "Keys - Search engine\n -----------------------------------------\n" << fmtBoldEnd;
help << DisplayKeys(Key.Enter) << "Add item to playlist and play/change option\n";
help << DisplayKeys(Key.Space) << "Add item to playlist\n";
help << DisplayKeys(Key.StartSearching) << "Start searching immediately\n\n\n";
result += " [.b]Keys - Media library\n -----------------------------------------[/b]\n";
result += DisplayKeys(&Key.VolumeDown[0], 1) + "Previous column\n";
result += DisplayKeys(&Key.VolumeUp[0], 1) + "Next column\n";
result += DisplayKeys(Key.Enter) + "Add to playlist and play song/album/artist's songs\n";
result += DisplayKeys(Key.Space) + "Add to playlist song/album/artist's songs\n";
result += DisplayKeys(Key.SwitchTagTypeList) + "Tag type list switcher (left column)\n\n\n";
help << " " << fmtBold << "Keys - Media library\n -----------------------------------------\n" << fmtBoldEnd;
help << DisplayKeys(&Key.VolumeDown[0], 1) << "Previous column\n";
help << DisplayKeys(&Key.VolumeUp[0], 1) << "Next column\n";
help << DisplayKeys(Key.Enter) << "Add to playlist and play song/album/artist's songs\n";
help << DisplayKeys(Key.Space) << "Add to playlist song/album/artist's songs\n";
help << DisplayKeys(Key.SwitchTagTypeList) << "Tag type list switcher (left column)\n\n\n";
result += " [.b]Keys - Playlist Editor\n -----------------------------------------[/b]\n";
result += DisplayKeys(&Key.VolumeDown[0], 1) + "Previous column\n";
result += DisplayKeys(&Key.VolumeUp[0], 1) + "Next column\n";
result += DisplayKeys(Key.Enter) + "Add item to playlist and play\n";
result += DisplayKeys(Key.Space) + "Add to playlist/select item\n";
help << " " << fmtBold << "Keys - Playlist Editorz\n -----------------------------------------\n" << fmtBoldEnd;
help << DisplayKeys(&Key.VolumeDown[0], 1) << "Previous column\n";
help << DisplayKeys(&Key.VolumeUp[0], 1) << "Next column\n";
help << DisplayKeys(Key.Enter) << "Add item to playlist and play\n";
help << DisplayKeys(Key.Space) << "Add to playlist/select item\n";
# ifndef HAVE_TAGLIB_H
result += DisplayKeys(Key.EditTags) + "Edit playlist's name\n";
help << DisplayKeys(Key.EditTags) << "Edit playlist's name\n";
# endif // ! HAVE_TAGLIB_H
result += DisplayKeys(Key.MvSongUp) + "Move item/group of items up\n";
result += DisplayKeys(Key.MvSongDown) + "Move item/group of items down\n";
help << DisplayKeys(Key.MvSongUp) << "Move item/group of items up\n";
help << DisplayKeys(Key.MvSongDown) << "Move item/group of items down\n";
result += "\n\n [.b]Keys - Lyrics\n -----------------------------------------[/b]\n";
result += DisplayKeys(Key.Space) + "Switch for following lyrics of now playing song\n";
help << "\n\n " << fmtBold << "Keys - Lyrics\n -----------------------------------------\n" << fmtBoldEnd;
help << DisplayKeys(Key.Space) << "Switch for following lyrics of now playing song\n";
# ifdef HAVE_TAGLIB_H
result += "\n\n [.b]Keys - Tag editor\n -----------------------------------------[/b]\n";
result += DisplayKeys(Key.Enter) + "Change tag/filename for one song (left column)\n";
result += DisplayKeys(Key.Enter) + "Perform operation on all/selected songs (middle column)\n";
result += DisplayKeys(Key.Space) + "Switch to albums/directories view (left column)\n";
result += DisplayKeys(Key.Space) + "Select/deselect song (right column)\n";
result += DisplayKeys(&Key.VolumeDown[0], 1) + "Previous column\n";
result += DisplayKeys(&Key.VolumeUp[0], 1) + "Next column\n";
help << "\n\n " << fmtBold << "Keys - Tag editor\n -----------------------------------------\n" << fmtBoldEnd;
help << DisplayKeys(Key.Enter) << "Change tag/filename for one song (left column)\n";
help << DisplayKeys(Key.Enter) << "Perform operation on all/selected songs (middle column)\n";
help << DisplayKeys(Key.Space) << "Switch to albums/directories view (left column)\n";
help << DisplayKeys(Key.Space) << "Select/deselect song (right column)\n";
help << DisplayKeys(&Key.VolumeDown[0], 1) << "Previous column\n";
help << DisplayKeys(&Key.VolumeUp[0], 1) << "Next column\n";
# endif // HAVE_TAGLIB_H
return result;
}

View File

@@ -23,7 +23,7 @@
#include "ncmpcpp.h"
string GetKeybindings();
void GetKeybindings(Scrollpad &);
#endif

View File

@@ -86,7 +86,7 @@ bool ParseArgv(int argc, char **argv)
# ifdef HAVE_TAGLIB_H
<< " taglib"
# endif
# ifdef UTF8_ENABLED
# ifdef _UTF8
<< " unicode"
# endif
<< endl;
@@ -462,7 +462,7 @@ string DisplaySongInColumns(const Song &s, void *s_template, const Menu<Song> *)
my_string_t result, v;
# ifdef UTF8_ENABLED
# ifdef _UTF8
const wstring space = L" ";
const wstring open_col = L"[.";
const wstring close_col = L"]";
@@ -534,7 +534,7 @@ string DisplaySongInColumns(const Song &s, void *s_template, const Menu<Song> *)
break;
}
v = TO_WSTRING(Window::OmitBBCodes(ss)).substr(0, width-1);
v = TO_WSTRING(ss.substr(0, width-1));
for (int i = v.length(); i < width; i++, v += space) { }
if (!color.empty())
{
@@ -822,14 +822,13 @@ string DisplaySong(const Song &s, void *s_template, const Menu<Song> *menu)
}
if (right && menu)
{
result = lresult + "[." + IntoStr(menu->GetWidth()-Window::RealLength(result)) + "]" + result;
result = lresult + "[." + IntoStr(menu->GetWidth()-result.length()) + "]" + result;
}
return result;
}
string GetInfo(Song &s)
void GetInfo(Song &s, Scrollpad &info)
{
string result;
# ifdef HAVE_TAGLIB_H
string path_to_file;
if (s.IsFromDB())
@@ -840,28 +839,27 @@ string GetInfo(Song &s)
s.SetComment(f.tag()->comment().to8Bit(UNICODE));
# endif // HAVE_TAGLIB_H
result = "[.b][." + Config.color1 + "]Filename: [/" + Config.color1 + "][." + Config.color2 + "][/b]" + s.GetName() + "[/" + Config.color2 + "]\n";
result += "[.b][." + Config.color1 + "]Directory: [/" + Config.color1 + "][." + Config.color2 + "][/b]" + s.GetDirectory() + "[/" + Config.color2 + "]\n\n";
result += "[.b][." + Config.color1 + "]Length: [/" + Config.color1 + "][." + Config.color2 + "][/b]" + s.GetLength() + "[/" + Config.color2 + "]\n";
info << fmtBold << clWhite << "Filename: " << fmtBoldEnd << clGreen << s.GetName() << "\n" << clEnd;
info << fmtBold << "Directory: " << fmtBoldEnd << clGreen << s.GetDirectory() + "\n\n" << clEnd;
info << fmtBold << "Length: " << fmtBoldEnd << clGreen << s.GetLength() + "\n" << clEnd;
# ifdef HAVE_TAGLIB_H
if (!f.isNull())
{
result += "[.b][." + Config.color1 + "]Bitrate: [/" + Config.color1 + "][." + Config.color2 + "][/b]" + IntoStr(f.audioProperties()->bitrate()) + " kbps[/" + Config.color2 + "]\n";
result += "[.b][." + Config.color1 + "]Sample rate: [/" + Config.color1 + "][." + Config.color2 + "][/b]" + IntoStr(f.audioProperties()->sampleRate()) + " Hz[/" + Config.color2 + "]\n";
result += "[.b][." + Config.color1 + "]Channels: [/" + Config.color1 + "][." + Config.color2 + "][/b]" + string(f.audioProperties()->channels() == 1 ? "Mono" : "Stereo") + "[/" + Config.color2 + "]\n";
info << fmtBold << "Bitrate: " << fmtBoldEnd << clGreen << f.audioProperties()->bitrate() << " kbps\n" << clEnd;
info << fmtBold << "Sample rate: " << fmtBoldEnd << clGreen << f.audioProperties()->sampleRate() << " Hz\n" << clEnd;
info << fmtBold << "Channels: " << fmtBoldEnd << clGreen << (f.audioProperties()->channels() == 1 ? "Mono" : "Stereo") << "\n" << clDefault;
}
# endif // HAVE_TAGLIB_H
result += "\n[.b]Title:[/b] " + s.GetTitle();
result += "\n[.b]Artist:[/b] " + s.GetArtist();
result += "\n[.b]Album:[/b] " + s.GetAlbum();
result += "\n[.b]Year:[/b] " + s.GetYear();
result += "\n[.b]Track:[/b] " + s.GetTrack();
result += "\n[.b]Genre:[/b] " + s.GetGenre();
result += "\n[.b]Composer:[/b] " + s.GetComposer();
result += "\n[.b]Performer:[/b] " + s.GetPerformer();
result += "\n[.b]Disc:[/b] " + s.GetDisc();
result += "\n[.b]Comment:[/b] " + s.GetComment();
return result;
info << fmtBold << "\nTitle: " << fmtBoldEnd << s.GetTitle();
info << fmtBold << "\nArtist: " << fmtBoldEnd << s.GetArtist();
info << fmtBold << "\nAlbum: " << fmtBoldEnd << s.GetAlbum();
info << fmtBold << "\nYear: " << fmtBoldEnd << s.GetYear();
info << fmtBold << "\nTrack: " << fmtBoldEnd << s.GetTrack();
info << fmtBold << "\nGenre: " << fmtBoldEnd << s.GetGenre();
info << fmtBold << "\nComposer: " << fmtBoldEnd << s.GetComposer();
info << fmtBold << "\nPerformer: " << fmtBoldEnd << s.GetPerformer();
info << fmtBold << "\nDisc: " << fmtBoldEnd << s.GetDisc();
info << fmtBold << "\nComment: " << fmtBoldEnd << s.GetComment();
}
void ShowMessage(const char *format, ...)
@@ -877,9 +875,9 @@ void ShowMessage(const char *format, ...)
wFooter->Bold(0);
va_list list;
va_start(list, format);
wmove(wFooter->RawWin(), Config.statusbar_visibility, 0);
vw_printw(wFooter->RawWin(), format, list);
wclrtoeol(wFooter->RawWin());
wmove(wFooter->Raw(), Config.statusbar_visibility, 0);
vw_printw(wFooter->Raw(), format, list);
wclrtoeol(wFooter->Raw());
va_end(list);
wFooter->Bold(1);
wFooter->Refresh();

View File

@@ -55,7 +55,7 @@ string DisplayStringPair(const StringPair &, void *, const Menu<StringPair> *);
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 GetInfo(Song &, Scrollpad &);
void ShowMessage(const char *, ...);
#endif

View File

@@ -26,13 +26,16 @@
#include "settings.h"
#include "song.h"
extern Scrollpad *sLyrics;
extern Scrollpad *sInfo;
const string artists_folder = home_folder + "/" + ".ncmpcpp/artists";
const string lyrics_folder = home_folder + "/" + ".lyrics";
#ifdef HAVE_CURL_CURL_H
extern pthread_t lyrics_downloader;
extern pthread_t artist_info_downloader;
pthread_mutex_t curl = PTHREAD_MUTEX_INITIALIZER;
bool artist_info_ready = 0;
bool lyrics_ready = 0;
#endif
namespace
@@ -74,18 +77,24 @@ void * GetArtistInfo(void *ptr)
const string fullpath = artists_folder + "/" + filename;
mkdir(artists_folder.c_str(), 0755);
string *result = new string();
string result;
std::ifstream input(fullpath.c_str());
if (input.is_open())
{
bool first = 1;
string line;
while (getline(input, line))
*result += line + "\n";
{
if (!first)
*sInfo << "\n";
*sInfo << line;
first = 0;
}
input.close();
*result = result->substr(0, result->length()-1);
artist_info_ready = 1;
pthread_exit(result);
sInfo->Flush();
artist_info_downloader = 0;
pthread_exit(NULL);
}
for (string::iterator it = artist.begin(); it != artist.end(); it++)
@@ -100,7 +109,7 @@ void * GetArtistInfo(void *ptr)
CURL *info = curl_easy_init();
curl_easy_setopt(info, CURLOPT_URL, url.c_str());
curl_easy_setopt(info, CURLOPT_WRITEFUNCTION, write_data);
curl_easy_setopt(info, CURLOPT_WRITEDATA, result);
curl_easy_setopt(info, CURLOPT_WRITEDATA, &result);
curl_easy_setopt(info, CURLOPT_CONNECTTIMEOUT, 10);
code = curl_easy_perform(info);
curl_easy_cleanup(info);
@@ -108,131 +117,137 @@ void * GetArtistInfo(void *ptr)
if (code != CURLE_OK)
{
*result = "Error while fetching artist's info: " + string(curl_easy_strerror(code));
artist_info_ready = 1;
pthread_exit(result);
*sInfo << "Error while fetching artist's info: " << curl_easy_strerror(code);
sInfo->Flush();
artist_info_downloader = 0;
pthread_exit(NULL);
}
size_t a, b;
bool erase = 0;
bool save = 1;
a = result->find("status=\"failed\"");
a = result.find("status=\"failed\"");
if (a != string::npos)
{
EscapeHtml(*result);
*result = "Last.fm returned an error message: " + *result;
artist_info_ready = 1;
pthread_exit(result);
EscapeHtml(result);
*sInfo << "Last.fm returned an error message: " << result;
sInfo->Flush();
artist_info_downloader = 0;
pthread_exit(NULL);
}
vector<string> similar;
for (size_t i = result->find("<name>"); i != string::npos; i = result->find("<name>"))
for (size_t i = result.find("<name>"); i != string::npos; i = result.find("<name>"))
{
(*result)[i] = '.';
size_t j = result->find("</name>");
(*result)[j] = '.';
result[i] = '.';
size_t j = result.find("</name>");
result[j] = '.';
i += 6;
similar.push_back(result->substr(i, j-i));
similar.push_back(result.substr(i, j-i));
EscapeHtml(similar.back());
}
vector<string> urls;
for (size_t i = result->find("<url>"); i != string::npos; i = result->find("<url>"))
for (size_t i = result.find("<url>"); i != string::npos; i = result.find("<url>"))
{
(*result)[i] = '.';
size_t j = result->find("</url>");
(*result)[j] = '.';
result[i] = '.';
size_t j = result.find("</url>");
result[j] = '.';
i += 5;
urls.push_back(result->substr(i, j-i));
urls.push_back(result.substr(i, j-i));
}
a = result->find("<content>")+9;
b = result->find("</content>");
a = result.find("<content>")+9;
b = result.find("</content>");
if (a == b)
{
*result = "No description available for this artist.";
result = "No description available for this artist.";
save = 0;
}
else
{
a += 9; // for <![CDATA[
b -= 3; // for ]]>
*result = result->substr(a, b-a);
result = result.substr(a, b-a);
}
EscapeHtml(*result);
for (size_t i = 0; i < result->length(); i++)
EscapeHtml(result);
for (size_t i = 0; i < result.length(); i++)
{
if (erase)
{
result->erase(result->begin()+i);
result.erase(result.begin()+i);
erase = 0;
}
if ((*result)[i] == 13)
if (result[i] == 13)
{
(*result)[i] = '\n';
result[i] = '\n';
erase = 1;
}
else if ((*result)[i] == '\t')
(*result)[i] = ' ';
else if (result[i] == '\t')
result[i] = ' ';
}
int i = result->length();
if (!isgraph((*result)[i-1]))
int i = result.length();
if (!isgraph(result[i-1]))
{
while (!isgraph((*result)[--i])) { }
*result = result->substr(0, i+1);
while (!isgraph(result[--i])) { }
result = result.substr(0, i+1);
}
*result += "\n\n[.b]Similar artists:[/b]\n";
for (size_t i = 1; i < similar.size(); i++)
*result += "\n [." + Config.color2 + "]*[/" + Config.color2 + "] " + similar[i] + " (" + urls[i] + ")";
*sInfo << result;
*result += "\n\n" + urls.front();
*sInfo << fmtBold << "\n\nSimilar artists:\n" << fmtBoldEnd;
for (size_t i = 1; i < similar.size(); i++)
*sInfo << "\n" << clGreen << " * " << clEnd << similar[i] << " (" << urls[i] << ")";
*sInfo << "\n\n" << urls.front();
if (save)
{
std::ofstream output(fullpath.c_str());
if (output.is_open())
{
output << *result;
output << TO_STRING(sInfo->Content());
output.close();
}
}
artist_info_ready = 1;
pthread_exit(result);
sInfo->Flush();
artist_info_downloader = 0;
pthread_exit(NULL);
}
#endif // HAVE_CURL_CURL_H
void * GetLyrics(void *song)
void *GetLyrics(void *song)
{
string artist = static_cast<Song *>(song)->GetArtist();
string title = static_cast<Song *>(song)->GetTitle();
const string filename = artist + " - " + title + ".txt";
string filename = artist + " - " + title + ".txt";
const string fullpath = lyrics_folder + "/" + filename;
mkdir(lyrics_folder.c_str(), 0755);
string *result = new string();
std::ifstream input(fullpath.c_str());
if (input.is_open())
{
bool first = 1;
string line;
while (getline(input, line))
*result += line + "\n";
input.close();
*result = result->substr(0, result->length()-1);
{
if (!first)
*sLyrics << "\n";
*sLyrics << line;
first = 0;
}
# ifdef HAVE_CURL_CURL_H
lyrics_ready = 1;
pthread_exit(result);
sLyrics->Flush();
lyrics_downloader = 0;
pthread_exit(NULL);
# endif
}
# ifdef HAVE_CURL_CURL_H
for (string::iterator it = artist.begin(); it != artist.end(); it++)
if (*it == ' ')
@@ -244,13 +259,19 @@ void * GetLyrics(void *song)
CURLcode code;
string url = "http://lyricwiki.org/api.php?artist=" + artist + "&song=" + title + "&fmt=xml";
string result;
string url = "http://lyricwiki.org/api.php?artist=";
url += artist;
url += "&song=";
url += title;
url += "&fmt=xml";
pthread_mutex_lock(&curl);
CURL *lyrics = curl_easy_init();
curl_easy_setopt(lyrics, CURLOPT_URL, url.c_str());
curl_easy_setopt(lyrics, CURLOPT_WRITEFUNCTION, write_data);
curl_easy_setopt(lyrics, CURLOPT_WRITEDATA, result);
curl_easy_setopt(lyrics, CURLOPT_WRITEDATA, &result);
curl_easy_setopt(lyrics, CURLOPT_CONNECTTIMEOUT, 10);
code = curl_easy_perform(lyrics);
curl_easy_cleanup(lyrics);
@@ -258,43 +279,49 @@ void * GetLyrics(void *song)
if (code != CURLE_OK)
{
*result = "Error while fetching lyrics: " + string(curl_easy_strerror(code));
lyrics_ready = 1;
pthread_exit(result);
*sLyrics << "Error while fetching lyrics: " << curl_easy_strerror(code);
sLyrics->Flush();
lyrics_downloader = 0;
pthread_exit(NULL);
}
int a, b;
a = result->find("<lyrics>")+8;
b = result->find("</lyrics>");
a = result.find("<lyrics>")+8;
b = result.find("</lyrics>");
*result = result->substr(a, b-a);
result = result.substr(a, b-a);
if (*result == "Not found")
if (result == "Not found")
{
lyrics_ready = 1;
pthread_exit(result);
*sLyrics << result;
sLyrics->Flush();
lyrics_downloader = 0;
pthread_exit(NULL);
}
for (size_t i = result->find("&lt;"); i != string::npos; i = result->find("&lt;"))
result->replace(i, 4, "<");
for (size_t i = result->find("&gt;"); i != string::npos; i = result->find("&gt;"))
result->replace(i, 4, ">");
for (size_t i = result.find("&lt;"); i != string::npos; i = result.find("&lt;"))
result.replace(i, 4, "<");
for (size_t i = result.find("&gt;"); i != string::npos; i = result.find("&gt;"))
result.replace(i, 4, ">");
EscapeHtml(*result);
EscapeHtml(result);
*sLyrics << result;
std::ofstream output(fullpath.c_str());
if (output.is_open())
{
output << *result;
output << result;
output.close();
}
lyrics_ready = 1;
pthread_exit(result);
sLyrics->Flush();
lyrics_downloader = 0;
pthread_exit(NULL);
# else
else
*result = "Local lyrics not found. As ncmpcpp has been compiled without curl support, you can put appropriate lyrics into ~/.lyrics directory (file syntax is \"ARTIST - TITLE.txt\") or recompile ncmpcpp with curl support.";
return result;
*sLyrics << "Local lyrics not found. As ncmpcpp has been compiled without curl support, you can put appropriate lyrics into ~/.lyrics directory (file syntax is \"ARTIST - TITLE.txt\") or recompile ncmpcpp with curl support.";
sLyrics->Flush();
return NULL;
# endif
}

View File

@@ -67,8 +67,8 @@ class Menu : public Window
void InsertSeparator(int where) { Insert(where, T(), 0, 1, 1); }
virtual string GetOption(int i = -1) const;
virtual void Refresh(bool redraw_whole_window = 0);
virtual void Go(Where);
virtual void Refresh();
virtual void Scroll(Where);
virtual void Highlight(int);
virtual void Reset();
virtual void Clear(bool clear_screen = 1);
@@ -90,8 +90,8 @@ class Menu : public Window
bool Empty() const { return itsOptions.empty(); }
bool IsBold(int = -1) const;
virtual bool IsStatic(int = -1) const;
virtual Window * Clone() const { return new Menu(*this); }
virtual Window * EmptyClone() const;
virtual Menu<T> *Clone() const { return new Menu<T>(*this); }
virtual Menu<T> *EmptyClone() const;
T & Back() { return itsOptions.back()->item; }
const T & Back() const { return itsOptions.back()->item; }
@@ -317,10 +317,11 @@ void Menu<T>::redraw_screen()
}
template <class T>
void Menu<T>::Refresh(bool redraw_whole_window)
void Menu<T>::Refresh()
{
bool redraw_whole_window = 1;
if (!itsOptions.empty() && is_static())
itsHighlight == 0 ? Go(wDown) : Go(wUp);
itsHighlight == 0 ? Scroll(wDown) : Scroll(wUp);
int MaxBeginning = itsOptions.size() < itsHeight ? 0 : itsOptions.size()-itsHeight;
if (itsBeginning > MaxBeginning)
@@ -376,7 +377,7 @@ void Menu<T>::Refresh(bool redraw_whole_window)
if (itsOptions[*it]->selected)
option += itsSelectedSuffix;
int strlength = itsOptions[*it]->location != lLeft && BBEnabled ? Window::RealLength(option) : option.length();
int strlength = option.length();
if (strlength)
{
@@ -429,7 +430,7 @@ void Menu<T>::Refresh(bool redraw_whole_window)
}
template <class T>
void Menu<T>::Go(Where where)
void Menu<T>::Scroll(Where where)
{
if (Empty())
return;
@@ -459,7 +460,7 @@ void Menu<T>::Go(Where where)
}
if (is_static())
{
itsHighlight == 0 ? Go(wDown) : Go(wUp);
itsHighlight == 0 ? Scroll(wDown) : Scroll(wUp);
}
break;
}
@@ -481,7 +482,7 @@ void Menu<T>::Go(Where where)
}
if (is_static())
{
itsHighlight == MaxHighlight ? Go(wUp) : Go(wDown);
itsHighlight == MaxHighlight ? Scroll(wUp) : Scroll(wDown);
}
break;
}
@@ -497,7 +498,7 @@ void Menu<T>::Go(Where where)
}
if (is_static())
{
itsHighlight == 0 ? Go(wDown) : Go(wUp);
itsHighlight == 0 ? Scroll(wDown) : Scroll(wUp);
}
redraw_screen();
break;
@@ -514,7 +515,7 @@ void Menu<T>::Go(Where where)
}
if (is_static())
{
itsHighlight == MaxHighlight ? Go(wUp) : Go(wDown);
itsHighlight == MaxHighlight ? Scroll(wUp) : Scroll(wDown);
}
redraw_screen();
break;
@@ -525,7 +526,7 @@ void Menu<T>::Go(Where where)
itsBeginning = 0;
if (is_static())
{
itsHighlight == 0 ? Go(wDown) : Go(wUp);
itsHighlight == 0 ? Scroll(wDown) : Scroll(wUp);
}
redraw_screen();
break;
@@ -536,7 +537,7 @@ void Menu<T>::Go(Where where)
itsBeginning = MaxBeginning;
if (is_static())
{
itsHighlight == MaxHighlight ? Go(wUp) : Go(wDown);
itsHighlight == MaxHighlight ? Scroll(wUp) : Scroll(wDown);
}
redraw_screen();
break;
@@ -702,9 +703,9 @@ bool Menu<T>::IsStatic(int option) const
}
template <class T>
Window * Menu<T>::EmptyClone() const
Menu<T> *Menu<T>::EmptyClone() const
{
return new Menu(GetStartX(), GetStartY(), GetWidth(), GetHeight(), itsTitle, itsBaseColor, itsBorder);
return new Menu<T>(GetStartX(), GetStartY(), GetWidth(), GetHeight(), itsTitle, itsBaseColor, itsBorder);
}
template <class T>

View File

@@ -47,30 +47,30 @@
#define REFRESH_MEDIA_LIBRARY_SCREEN \
do { \
mLibArtists->Display(redraw_screen); \
mLibArtists->Display(); \
mvvline(main_start_y, middle_col_startx-1, 0, main_height); \
mLibAlbums->Display(redraw_screen); \
mLibAlbums->Display(); \
mvvline(main_start_y, right_col_startx-1, 0, main_height); \
mLibSongs->Display(redraw_screen); \
mLibSongs->Display(); \
if (mLibAlbums->Empty()) \
mLibAlbums->WriteXY(0, 0, "No albums found."); \
} while (0)
#define REFRESH_PLAYLIST_EDITOR_SCREEN \
do { \
mPlaylistList->Display(redraw_screen); \
mPlaylistList->Display(); \
mvvline(main_start_y, middle_col_startx-1, 0, main_height); \
mPlaylistEditor->Display(redraw_screen); \
mPlaylistEditor->Display(); \
} while (0)
#ifdef HAVE_TAGLIB_H
# define REFRESH_TAG_EDITOR_SCREEN \
do { \
mEditorLeftCol->Display(redraw_screen); \
mEditorLeftCol->Display(); \
mvvline(main_start_y, middle_col_startx-1, 0, main_height); \
mEditorTagTypes->Display(redraw_screen); \
mEditorTagTypes->Display(); \
mvvline(main_start_y, right_col_startx-1, 0, main_height); \
mEditorTags->Display(redraw_screen); \
mEditorTags->Display(); \
} while (0)
#endif // HAVE_TAGLIB_H
@@ -138,8 +138,6 @@ NcmpcppScreen prev_screen;
#ifdef HAVE_CURL_CURL_H
pthread_t lyrics_downloader;
pthread_t artist_info_downloader;
extern bool artist_info_ready;
extern bool lyrics_ready;
#endif
bool dont_change_now_playing = 0;
@@ -202,14 +200,10 @@ int main(int argc, char *argv[])
if (!ConnectToMPD())
return -1;
setlocale(LC_ALL, "");
initscr();
noecho();
cbreak();
curs_set(0);
InitScreen();
if (Config.colors_enabled)
Window::EnableColors();
//if (Config.colors_enabled)
// Window::EnableColors();
int main_start_y = 2;
int main_height = LINES-4;
@@ -223,7 +217,6 @@ int main(int argc, char *argv[])
main_height++;
mPlaylist = new Menu<Song>(0, main_start_y, COLS, main_height, Config.columns_in_playlist ? DisplayColumns(Config.song_columns_list_format) : "", Config.main_color, brNone);
mPlaylist->AutoRefresh(0);
mPlaylist->SetTimeout(ncmpcpp_window_timeout);
mPlaylist->HighlightColor(Config.main_highlight_color);
mPlaylist->SetSelectPrefix(Config.selected_item_prefix);
@@ -311,12 +304,13 @@ int main(int argc, char *argv[])
sHelp = new Scrollpad(0, main_start_y, COLS, main_height, "", Config.main_color, brNone);
sHelp->SetTimeout(ncmpcpp_window_timeout);
sHelp->Add(GetKeybindings());
GetKeybindings(*sHelp);
sHelp->Flush();
sLyrics = static_cast<Scrollpad *>(sHelp->EmptyClone());
sLyrics = sHelp->EmptyClone();
sLyrics->SetTimeout(ncmpcpp_window_timeout);
sInfo = static_cast<Scrollpad *>(sHelp->EmptyClone());
sInfo = sHelp->EmptyClone();
sInfo->SetTimeout(ncmpcpp_window_timeout);
if (Config.header_visibility)
@@ -356,6 +350,12 @@ int main(int argc, char *argv[])
signal(SIGPIPE, SIG_IGN);
# ifdef HAVE_CURL_CURL_H
pthread_attr_t attr_detached;
pthread_attr_init(&attr_detached);
pthread_attr_setdetachstate(&attr_detached, PTHREAD_CREATE_DETACHED);
# endif // HAVE_CURL_CURL_H
while (!main_exit)
{
if (!Mpd->Connected())
@@ -430,7 +430,7 @@ int main(int argc, char *argv[])
wHeader->Bold(1);
if (browsed_dir.length() > max_length_without_scroll)
{
# ifdef UTF8_ENABLED
# ifdef _UTF8
wbrowseddir += L" ** ";
# else
wbrowseddir += " ** ";
@@ -460,10 +460,10 @@ int main(int argc, char *argv[])
wHeader->SetColor(Config.volume_color);
wHeader->WriteXY(max_allowed_title_length, 0, volume_state);
wHeader->SetColor(Config.header_color);
wHeader->Refresh();
redraw_header = 0;
}
// header stuff end
// media library stuff
if (current_screen == csLibrary)
{
@@ -704,7 +704,7 @@ int main(int argc, char *argv[])
if (redraw_screen && wCurrent == mEditorTagTypes && mEditorTagTypes->GetChoice() < 13)
{
mEditorTags->Refresh(1);
mEditorTags->Refresh();
redraw_screen = 0;
}
else if (mEditorTagTypes->GetChoice() >= 13)
@@ -722,36 +722,11 @@ int main(int argc, char *argv[])
else
reload_lyrics = 0;
}
# ifdef HAVE_CURL_CURL_H
if (artist_info_ready)
{
void *result;
string *str_result = 0;
pthread_join(artist_info_downloader, &result);
str_result = static_cast<string *>(result);
sInfo->Add(*str_result);
delete str_result;
artist_info_downloader = 0;
artist_info_ready = 0;
}
else if (lyrics_ready)
{
void *result;
string *str_result = 0;
pthread_join(lyrics_downloader, &result);
str_result = static_cast<string *>(result);
sLyrics->Add(*str_result);
delete str_result;
lyrics_downloader = 0;
lyrics_ready = 0;
}
# endif
// lyrics end
if (Config.columns_in_playlist && wCurrent == mPlaylist)
wCurrent->Display(redraw_screen);
wCurrent->Display();
else
wCurrent->Refresh(redraw_screen);
wCurrent->Refresh();
redraw_screen = 0;
wCurrent->ReadKey(input);
@@ -811,14 +786,14 @@ int main(int argc, char *argv[])
wCurrent->SetTimeout(50);
while (Keypressed(input, Key.Up))
{
wCurrent->Go(wUp);
wCurrent->Scroll(wUp);
wCurrent->Refresh();
wCurrent->ReadKey(input);
}
wCurrent->SetTimeout(ncmpcpp_window_timeout);
}
else
wCurrent->Go(wUp);
wCurrent->Scroll(wUp);
}
else if (Keypressed(input, Key.Down))
{
@@ -827,30 +802,30 @@ int main(int argc, char *argv[])
wCurrent->SetTimeout(50);
while (Keypressed(input, Key.Down))
{
wCurrent->Go(wDown);
wCurrent->Scroll(wDown);
wCurrent->Refresh();
wCurrent->ReadKey(input);
}
wCurrent->SetTimeout(ncmpcpp_window_timeout);
}
else
wCurrent->Go(wDown);
wCurrent->Scroll(wDown);
}
else if (Keypressed(input, Key.PageUp))
{
wCurrent->Go(wPageUp);
wCurrent->Scroll(wPageUp);
}
else if (Keypressed(input, Key.PageDown))
{
wCurrent->Go(wPageDown);
wCurrent->Scroll(wPageDown);
}
else if (Keypressed(input, Key.Home))
{
wCurrent->Go(wHome);
wCurrent->Scroll(wHome);
}
else if (Keypressed(input, Key.End))
{
wCurrent->Go(wEnd);
wCurrent->Scroll(wEnd);
}
else if (input == KEY_RESIZE)
{
@@ -1315,8 +1290,8 @@ int main(int argc, char *argv[])
ShowMessage("Searching finished!");
for (int i = 0; i < search_engine_static_options-4; i++)
mSearcher->MakeStatic(i, 1);
mSearcher->Go(wDown);
mSearcher->Go(wDown);
mSearcher->Scroll(wDown);
mSearcher->Scroll(wDown);
}
else
ShowMessage("No results found");
@@ -1461,7 +1436,7 @@ int main(int argc, char *argv[])
FreeSongList(list);
if (Keypressed(input, Key.Space))
{
wCurrent->Go(wDown);
wCurrent->Scroll(wDown);
if (wCurrent == mLibArtists)
{
mLibAlbums->Clear(0);
@@ -1548,7 +1523,7 @@ int main(int argc, char *argv[])
}
FreeSongList(list);
if (Keypressed(input, Key.Space))
wCurrent->Go(wDown);
wCurrent->Scroll(wDown);
break;
}
# ifdef HAVE_TAGLIB_H
@@ -1668,7 +1643,7 @@ int main(int argc, char *argv[])
UnlockStatusbar();
if (!new_name.empty() && new_name != old_name)
s.SetNewName(new_name + extension);
mEditorTags->Go(wDown);
mEditorTags->Scroll(wDown);
}
continue;
}
@@ -1732,7 +1707,7 @@ int main(int argc, char *argv[])
UnlockStatusbar();
if (new_tag != mEditorTags->GetOption())
(mEditorTags->Current().*set)(new_tag);
mEditorTags->Go(wDown);
mEditorTags->Scroll(wDown);
}
}
# endif // HAVE_TAGLIB_H
@@ -1748,7 +1723,7 @@ int main(int argc, char *argv[])
{
int i = wCurrent->GetChoice();
wCurrent->Select(i, !wCurrent->Selected(i));
wCurrent->Go(wDown);
wCurrent->Scroll(wDown);
}
}
else
@@ -1825,7 +1800,7 @@ int main(int argc, char *argv[])
break;
}
}
mBrowser->Go(wDown);
mBrowser->Scroll(wDown);
}
else if (current_screen == csSearcher && mSearcher->Current().first == ".")
{
@@ -1855,7 +1830,7 @@ int main(int argc, char *argv[])
mSearcher->BoldOption(mSearcher->GetChoice(), 1);
}
}
mSearcher->Go(wDown);
mSearcher->Scroll(wDown);
}
else if (current_screen == csLibrary)
goto ENTER_LIBRARY_SCREEN; // sorry, but that's stupid to copy the same code here.
@@ -2203,7 +2178,7 @@ int main(int argc, char *argv[])
timer = time(NULL);
to--;
mPlaylist->Swap(to, to+1);
mPlaylist->Go(wUp);
mPlaylist->Scroll(wUp);
mPlaylist->Refresh();
mPlaylist->ReadKey(input);
}
@@ -2249,7 +2224,7 @@ int main(int argc, char *argv[])
timer = time(NULL);
to--;
mPlaylistEditor->Swap(to, to+1);
mPlaylistEditor->Go(wUp);
mPlaylistEditor->Scroll(wUp);
mPlaylistEditor->Refresh();
mPlaylistEditor->ReadKey(input);
}
@@ -2306,7 +2281,7 @@ int main(int argc, char *argv[])
timer = time(NULL);
to++;
mPlaylist->Swap(to, to-1);
mPlaylist->Go(wDown);
mPlaylist->Scroll(wDown);
mPlaylist->Refresh();
mPlaylist->ReadKey(input);
}
@@ -2353,7 +2328,7 @@ int main(int argc, char *argv[])
timer = time(NULL);
to++;
mPlaylistEditor->Swap(to, to-1);
mPlaylistEditor->Go(wDown);
mPlaylistEditor->Scroll(wDown);
mPlaylistEditor->Refresh();
mPlaylistEditor->ReadKey(input);
}
@@ -2434,9 +2409,9 @@ int main(int argc, char *argv[])
double progressbar_size = (double)songpos/(s.GetTotalLength());
int howlong = wFooter->GetWidth()*progressbar_size;
mvwhline(wFooter->RawWin(), 0, 0, 0, wFooter->GetWidth());
mvwhline(wFooter->RawWin(), 0, 0, '=',howlong);
mvwaddch(wFooter->RawWin(), 0, howlong, '>');
mvwhline(wFooter->Raw(), 0, 0, 0, wFooter->GetWidth());
mvwhline(wFooter->Raw(), 0, 0, '=',howlong);
mvwaddch(wFooter->Raw(), 0, howlong, '>');
wFooter->Bold(0);
wFooter->Refresh();
}
@@ -2902,17 +2877,17 @@ int main(int argc, char *argv[])
mDialog->ReadKey(input);
if (Keypressed(input, Key.Up))
mDialog->Go(wUp);
mDialog->Scroll(wUp);
else if (Keypressed(input, Key.Down))
mDialog->Go(wDown);
mDialog->Scroll(wDown);
else if (Keypressed(input, Key.PageUp))
mDialog->Go(wPageUp);
mDialog->Scroll(wPageUp);
else if (Keypressed(input, Key.PageDown))
mDialog->Go(wPageDown);
mDialog->Scroll(wPageDown);
else if (Keypressed(input, Key.Home))
mDialog->Go(wHome);
mDialog->Scroll(wHome);
else if (Keypressed(input, Key.End))
mDialog->Go(wEnd);
mDialog->Scroll(wEnd);
}
int id = mDialog->GetChoice();
@@ -2927,7 +2902,7 @@ int main(int argc, char *argv[])
REFRESH_PLAYLIST_EDITOR_SCREEN;
}
else
wCurrent->Refresh(1);
wCurrent->Refresh();
if (id == 0)
{
@@ -3040,7 +3015,7 @@ int main(int argc, char *argv[])
ShowMessage("Searching...");
for (int i = (wCurrent == mSearcher ? search_engine_static_options-1 : 0); i < wCurrent->Size(); i++)
{
string name = Window::OmitBBCodes(wCurrent->GetOption(i));
string name = wCurrent->GetOption(i);
ToLower(name);
if (name.find(findme) != string::npos && !wCurrent->IsStatic(i))
{
@@ -3218,7 +3193,8 @@ int main(int argc, char *argv[])
redraw_header = 1;
info_title = "Song info";
sInfo->Clear();
sInfo->Add(GetInfo(*s));
GetInfo(*s, *sInfo);
sInfo->Flush();
sInfo->Hide();
}
}
@@ -3293,7 +3269,9 @@ int main(int argc, char *argv[])
sInfo->WriteXY(0, 0, "Fetching artist's info...");
sInfo->Refresh();
if (!artist_info_downloader)
pthread_create(&artist_info_downloader, NULL, GetArtistInfo, artist);
{
pthread_create(&artist_info_downloader, &attr_detached, GetArtistInfo, artist);
}
}
else
delete artist;
@@ -3383,11 +3361,11 @@ int main(int argc, char *argv[])
sLyrics->Refresh();
# ifdef HAVE_CURL_CURL_H
if (!lyrics_downloader)
pthread_create(&lyrics_downloader, NULL, GetLyrics, s);
{
pthread_create(&lyrics_downloader, &attr_detached, GetLyrics, s);
}
# else
string *lyrics = static_cast<string *>(GetLyrics(s));
sLyrics->Add(*lyrics);
delete lyrics;
GetLyrics(s);
# endif
}
}
@@ -3551,8 +3529,7 @@ int main(int argc, char *argv[])
// key mapping end
}
Mpd->Disconnect();
curs_set(1);
endwin();
DestroyScreen();
return 0;
}

View File

@@ -20,11 +20,17 @@
#include "scrollpad.h"
Scrollpad::Scrollpad(int startx, int starty, int width, int height, const string &title, Color color, Border border) :
Window(startx, starty, width, height, title, color, border),
itsBeginning(0),
itsRealHeight(1),
itsXPos(0)
Scrollpad::Scrollpad(size_t startx,
size_t starty,
size_t width,
size_t height,
const string &title,
Color color,
Border border)
: Window(startx, starty, width, height, title, color, border),
itsBeginning(0),
itsRealHeight(1),
itsXPos(0)
{
delwin(itsWindow);
itsWindow = newpad(itsHeight, itsWidth);
@@ -34,32 +40,21 @@ Scrollpad::Scrollpad(int startx, int starty, int width, int height, const string
Scrollpad::Scrollpad(const Scrollpad &s) : Window(s)
{
itsContent = s.itsContent;
itsRawContent = s.itsRawContent;
itsBuffer << s.itsBuffer;
itsBeginning = s.itsBeginning;
itsRealHeight = s.itsRealHeight;
itsXPos = s.itsXPos;
}
void Scrollpad::Add(string str)
void Scrollpad::Flush()
{
if (itsXPos > 0 && (str[0] != ' ' || str[0] != '\n'))
str = " " + str;
itsRealHeight = 1;
itsRawContent += str;
std::basic_string<my_char_t> s = itsBuffer.Str();
# ifdef UTF8_ENABLED
wstring s = ToWString(str);
wstring tmp;
# else
string &s = str;
string tmp;
# endif
int x_pos = 0;
int space_pos = 0;
int x_pos;
int space_pos;
int tab_size;
bool collect = 0;
for (size_t i = 0; i < s.length(); i++)
{
@@ -67,7 +62,7 @@ void Scrollpad::Add(string str)
if (s[i] != '\t')
{
# ifdef UTF8_ENABLED
# ifdef _UTF8
itsXPos += wcwidth(s[i]);
# else
itsXPos++;
@@ -76,41 +71,13 @@ void Scrollpad::Add(string str)
else
itsXPos += tab_size;
if (BBEnabled)
{
if (s[i] == '[' && (s[i+1] == '.' || s[i+1] == '/'))
collect = 1;
if (collect)
{
if (s[i] != '[')
{
tmp += s[i];
if (tmp.length() > 10) // the longest bbcode is 10 chars long
collect = 0;
}
else
tmp = s[i];
}
if (s[i] == ']')
collect = 0;
if (!collect && !tmp.empty())
{
if (IsValidColor(TO_STRING(tmp)))
itsXPos -= tmp.length();
tmp.clear();
}
}
if (s[i] == ' ') // if space, remember its position;
{
space_pos = i;
x_pos = itsXPos;
}
if (!collect && itsXPos >= itsWidth)
if (itsXPos >= itsWidth)
{
// if line is over, there was at least one space in this line and we are in the middle of the word, restore position to last known space and make it EOL
if (space_pos > 0 && (s[i] != ' ' || s[i+1] != ' '))
@@ -121,15 +88,17 @@ void Scrollpad::Add(string str)
}
}
if (!collect && (itsXPos >= itsWidth || s[i] == '\n'))
if (itsXPos >= itsWidth || s[i] == '\n')
{
itsRealHeight++;
itsXPos = 0;
space_pos = 0;
}
}
itsContent += TO_STRING(s);
Recreate();
itsBuffer.SetTemp(&s);
reinterpret_cast<Window &>(*this) << itsBuffer;
itsBuffer.SetTemp(0);
}
void Scrollpad::Recreate()
@@ -139,16 +108,25 @@ void Scrollpad::Recreate()
SetTimeout(itsWindowTimeout);
SetColor(itsBaseColor, itsBgColor);
keypad(itsWindow, 1);
Write(itsContent.c_str());
}
void Scrollpad::Refresh(bool)
void Scrollpad::Refresh()
{
prefresh(itsWindow, itsBeginning, 0, itsStartY, itsStartX, itsStartY+itsHeight-1, itsStartX+itsWidth);
}
void Scrollpad::Resize(int width, int height)
void Scrollpad::MoveTo(size_t x, size_t y)
{
itsStartX = x;
itsStartY = y;
}
void Scrollpad::Resize(size_t width, size_t height)
{
if (width+itsStartX > size_t(COLS)
|| height+itsStartY > size_t(LINES))
throw BadSize();
if (itsBorder != brNone)
{
delwin(itsWinBorder);
@@ -161,48 +139,45 @@ void Scrollpad::Resize(int width, int height)
if (!itsTitle.empty())
width -= 2;
if (height > 0 && width > 0)
{
itsHeight = height;
itsWidth = width;
itsBeginning = 0;
itsRealHeight = 1;
itsXPos = 0;
itsContent.clear();
string tmp = itsRawContent;
itsRawContent.clear();
Add(tmp);
Recreate();
}
itsHeight = height;
itsWidth = width;
itsBeginning = 0;
itsRealHeight = itsHeight;
itsXPos = 0;
Flush();
}
void Scrollpad::Go(Where where)
void Scrollpad::Scroll(Where where)
{
int MaxBeginning = itsContent.size() < itsHeight ? 0 : itsRealHeight-itsHeight;
int MaxBeginning = /*itsContent.size() < itsHeight ? 0 : */itsRealHeight-itsHeight;
switch (where)
{
case wUp:
{
if (itsBeginning > 0) itsBeginning--; // for scrolling
if (itsBeginning > 0)
itsBeginning--;
break;
}
case wDown:
{
if (itsBeginning < MaxBeginning) itsBeginning++; // scroll
if (itsBeginning < MaxBeginning)
itsBeginning++;
break;
}
case wPageUp:
{
itsBeginning -= itsHeight;
if (itsBeginning < 0) itsBeginning = 0;
if (itsBeginning < 0)
itsBeginning = 0;
break;
}
case wPageDown:
{
itsBeginning += itsHeight;
if (itsBeginning > MaxBeginning) itsBeginning = MaxBeginning;
if (itsBeginning > MaxBeginning)
itsBeginning = MaxBeginning;
break;
}
case wHome:
@@ -218,24 +193,44 @@ void Scrollpad::Go(Where where)
}
}
void Scrollpad::Clear(bool clear_screen)
void Scrollpad::Clear(bool clrscr)
{
itsBeginning = 0;
itsRealHeight = 1;
itsRealHeight = itsHeight;
itsXPos = 0;
itsContent.clear();
itsRawContent.clear();
itsBuffer.Clear();
wclear(itsWindow);
delwin(itsWindow);
itsWindow = newpad(itsHeight, itsWidth);
SetTimeout(itsWindowTimeout);
SetColor(itsColor, itsBgColor);
keypad(itsWindow, 1);
if (clear_screen)
if (clrscr)
Window::Clear();
}
Window * Scrollpad::EmptyClone() const
Scrollpad &Scrollpad::operator<<(std::ostream &(*os)(std::ostream&))
{
itsBuffer << os;
return *this;
}
#ifdef _UTF8
Scrollpad &Scrollpad::operator<<(const char *s)
{
wchar_t *ws = ToWString(s);
itsBuffer << ws;
delete [] ws;
return *this;
}
Scrollpad &Scrollpad::operator<<(const std::string &s)
{
return operator<<(s.c_str());
}
#endif // _UTF8
Scrollpad *Scrollpad::EmptyClone() const
{
return new Scrollpad(GetStartX(), GetStartY(), GetWidth(), GetHeight(), itsTitle, itsBaseColor, itsBorder);
}

View File

@@ -22,28 +22,50 @@
#define HAVE_SCROLLPAD_H
#include "window.h"
#include "strbuffer.h"
class Scrollpad: public Window
{
public:
Scrollpad(int, int, int, int, const string &, Color, Border);
Scrollpad(size_t, size_t, size_t, size_t, const std::string &, Color, Border);
Scrollpad(const Scrollpad &);
virtual ~Scrollpad() {}
virtual void Add(string);
virtual void Refresh(bool = 0);
virtual void Go(Where);
virtual void Resize(int, int);
virtual void Clear(bool clear_screen = 1);
virtual Window * Clone() const { return new Scrollpad(*this); }
virtual Window * EmptyClone() const;
virtual ~Scrollpad() { }
void Flush();
std::basic_string<my_char_t> Content() { return itsBuffer.Str(); }
virtual void Refresh();
virtual void Scroll(Where);
virtual void MoveTo(size_t, size_t);
virtual void Resize(size_t, size_t);
virtual void Clear(bool = 1);
template <class T> Scrollpad &operator<<(const T &t)
{
itsBuffer << t;
return *this;
}
Scrollpad &operator<<(std::ostream &(*os)(std::ostream &));
# ifdef _UTF8
Scrollpad &operator<<(const char *s);
Scrollpad &operator<<(const std::string &s);
# endif // _UTF8
virtual Scrollpad *Clone() const { return new Scrollpad(*this); }
virtual Scrollpad *EmptyClone() const;
protected:
virtual void Recreate();
string itsContent;
string itsRawContent;
basic_buffer<my_char_t> itsBuffer;
int itsBeginning;
int itsRealHeight;
int itsXPos;
size_t itsRealHeight;
size_t itsXPos;
};
#endif

View File

@@ -30,7 +30,7 @@ string UNKNOWN_ALBUM;
void DefineEmptyTags()
{
if (Config.empty_tags_color != clDefault)
/*if (Config.empty_tags_color != clDefault)
{
const string et_col = IntoStr(Config.empty_tags_color);
EMPTY_TAG = "[." + et_col + "]<empty>[/" + et_col + "]";
@@ -39,12 +39,12 @@ void DefineEmptyTags()
UNKNOWN_ALBUM = "[." + et_col + "]<no album>[/" + et_col + "]";
}
else
{
{*/
EMPTY_TAG = "<empty>";
UNKNOWN_ARTIST = "<no artist>";
UNKNOWN_TITLE = "<no title>";
UNKNOWN_ALBUM = "<no album";
}
UNKNOWN_ARTIST = "<empty>";
UNKNOWN_TITLE = "<empty>";
UNKNOWN_ALBUM = "<empty>";
// }
}
Song::Song(mpd_Song *s, bool copy_ptr) : itsSong(s),

View File

@@ -134,8 +134,6 @@ void NcmpcppStatusChanged(Connection *Mpd, StatusChanges changed, void *)
static string player_state;
int sx, sy;
wFooter->DisableBB();
wFooter->AutoRefresh(0);
wFooter->Bold(1);
wFooter->GetXY(sx, sy);
@@ -174,7 +172,7 @@ void NcmpcppStatusChanged(Connection *Mpd, StatusChanges changed, void *)
{
if (!playlist_length || mPlaylist->Size() < mPlaylist->GetHeight())
mPlaylist->Window::Clear();
mPlaylist->Refresh(1);
mPlaylist->Refresh();
}
}
else
@@ -263,7 +261,7 @@ void NcmpcppStatusChanged(Connection *Mpd, StatusChanges changed, void *)
{
WindowTitle("ncmpc++ ver. "VERSION);
wFooter->SetColor(Config.progressbar_color);
mvwhline(wFooter->RawWin(), 0, 0, 0, wFooter->GetWidth());
mvwhline(wFooter->Raw(), 0, 0, 0, wFooter->GetWidth());
wFooter->SetColor(Config.statusbar_color);
mPlaylist->BoldOption(old_playing, 0);
now_playing = -1;
@@ -291,7 +289,7 @@ void NcmpcppStatusChanged(Connection *Mpd, StatusChanges changed, void *)
repeat_one_allowed = 0;
if (!Mpd->GetElapsedTime())
mvwhline(wFooter->RawWin(), 0, 0, 0, wFooter->GetWidth());
mvwhline(wFooter->Raw(), 0, 0, 0, wFooter->GetWidth());
if (Config.now_playing_lyrics && !Config.repeat_one_mode && current_screen == csLyrics && prev_screen == csPlaylist)
reload_lyrics = 1;
@@ -330,7 +328,7 @@ void NcmpcppStatusChanged(Connection *Mpd, StatusChanges changed, void *)
wFooter->Bold(0);
if (playing_song.length() > max_length_without_scroll)
{
# ifdef UTF8_ENABLED
# ifdef _UTF8
playing_song += L" ** ";
# else
playing_song += " ** ";
@@ -354,11 +352,11 @@ void NcmpcppStatusChanged(Connection *Mpd, StatusChanges changed, void *)
double progressbar_size = (double)elapsed/(s.GetTotalLength());
int howlong = wFooter->GetWidth()*progressbar_size;
wFooter->SetColor(Config.progressbar_color);
mvwhline(wFooter->RawWin(), 0, 0, 0, wFooter->GetWidth());
mvwhline(wFooter->Raw(), 0, 0, 0, wFooter->GetWidth());
if (s.GetTotalLength())
{
mvwhline(wFooter->RawWin(), 0, 0, '=',howlong);
mvwaddch(wFooter->RawWin(), 0, howlong, '>');
mvwhline(wFooter->Raw(), 0, 0, '=',howlong);
mvwaddch(wFooter->Raw(), 0, howlong, '>');
}
wFooter->SetColor(Config.statusbar_color);
}
@@ -413,10 +411,9 @@ void NcmpcppStatusChanged(Connection *Mpd, StatusChanges changed, void *)
if (mpd_db_updating)
switch_state += mpd_db_updating;
wHeader->DisableBB();
wHeader->Bold(1);
wHeader->SetColor(Config.state_line_color);
mvwhline(wHeader->RawWin(), 1, 0, 0, wHeader->GetWidth());
mvwhline(wHeader->Raw(), 1, 0, 0, wHeader->GetWidth());
if (!switch_state.empty())
{
wHeader->WriteXY(wHeader->GetWidth()-switch_state.length()-3, 1, "[");
@@ -425,10 +422,8 @@ void NcmpcppStatusChanged(Connection *Mpd, StatusChanges changed, void *)
wHeader->SetColor(Config.state_line_color);
wHeader->WriteXY(wHeader->GetWidth()-2, 1, "]");
}
wHeader->Refresh();
wHeader->SetColor(Config.header_color);
wHeader->Bold(0);
wHeader->EnableBB();
header_update_status = 0;
}
if ((changed.Volume) && Config.header_visibility)
@@ -439,12 +434,11 @@ void NcmpcppStatusChanged(Connection *Mpd, StatusChanges changed, void *)
wHeader->WriteXY(wHeader->GetWidth()-volume_state.length(), 0, volume_state);
wHeader->SetColor(Config.header_color);
}
wHeader->Refresh();
if (current_screen == csPlaylist)
mPlaylist->Refresh();
wFooter->Bold(0);
wFooter->GotoXY(sx, sy);
wFooter->Refresh();
wFooter->AutoRefresh(1);
wFooter->EnableBB();
}

View File

@@ -107,7 +107,7 @@ namespace
string GenerateFilename(const Song &s, string &pattern)
{
string result = Window::OmitBBCodes(DisplaySong(s, &pattern));
string result = DisplaySong(s, &pattern);
EscapeUnallowedChars(result);
return result;
}
@@ -440,9 +440,9 @@ void __deal_with_filenames(SongList &v)
Main->Refresh();
Main->ReadKey(input);
if (Keypressed(input, Key.Down))
Main->Go(wDown);
Main->Scroll(wDown);
else if (Keypressed(input, Key.Up))
Main->Go(wUp);
Main->Scroll(wUp);
}
width = COLS*0.9;
@@ -465,7 +465,7 @@ void __deal_with_filenames(SongList &v)
{
Legend = new Scrollpad((COLS-width)/2+one_width, (LINES-height)/2, two_width, height, "Legend", Config.main_color, Config.window_border);
Legend->SetTimeout(ncmpcpp_window_timeout);
Legend->Add("%a - artist\n");
/* Legend->Add("%a - artist\n");
Legend->Add("%t - title\n");
Legend->Add("%b - album\n");
Legend->Add("%y - year\n");
@@ -477,7 +477,7 @@ void __deal_with_filenames(SongList &v)
Legend->Add("%C - comment\n\n");
Legend->Add("[.b]Files:[/b]\n");
for (SongList::const_iterator it = v.begin(); it != v.end(); it++)
Legend->Add("[." + Config.color2 + "]*[/" + Config.color2 + "] " + (*it)->GetName() + "\n");
Legend->Add("[." + Config.color2 + "]*[/" + Config.color2 + "] " + (*it)->GetName() + "\n");*/
Preview = static_cast<Scrollpad *>(Legend->EmptyClone());
Preview->SetTitle("Preview");
@@ -517,17 +517,17 @@ void __deal_with_filenames(SongList &v)
Active->ReadKey(input);
if (Keypressed(input, Key.Up))
Active->Go(wUp);
Active->Scroll(wUp);
else if (Keypressed(input, Key.Down))
Active->Go(wDown);
Active->Scroll(wDown);
else if (Keypressed(input, Key.PageUp))
Active->Go(wPageUp);
Active->Scroll(wPageUp);
else if (Keypressed(input, Key.PageDown))
Active->Go(wPageDown);
Active->Scroll(wPageDown);
else if (Keypressed(input, Key.Home))
Active->Go(wHome);
Active->Scroll(wHome);
else if (Keypressed(input, Key.End))
Active->Go(wEnd);
Active->Scroll(wEnd);
else if (Keypressed(input, Key.Enter) && Active == Main)
{
switch (Main->GetRealChoice())
@@ -559,8 +559,8 @@ void __deal_with_filenames(SongList &v)
{
if (preview)
{
Preview->Add("[.b]" + s.GetName() + ":[/b]\n");
Preview->Add(ParseFilename(s, Config.pattern, preview) + "\n");
// Preview->Add("[.b]" + s.GetName() + ":[/b]\n");
// Preview->Add(ParseFilename(s, Config.pattern, preview) + "\n");
}
else
ParseFilename(s, Config.pattern, preview);
@@ -585,7 +585,7 @@ void __deal_with_filenames(SongList &v)
}
if (!preview)
s.SetNewName(new_file + extension);
Preview->Add(file + " [." + Config.color2 + "]->[/" + Config.color2 + "] " + new_file + extension + "\n\n");
// Preview->Add(file + " [." + Config.color2 + "]->[/" + Config.color2 + "] " + new_file + extension + "\n\n");
s.GetEmptyFields(0);
}
}
@@ -635,7 +635,7 @@ void __deal_with_filenames(SongList &v)
else if (Keypressed(input, Key.VolumeUp) && Active == Main)
{
Active->SetBorder(Config.window_border);
Active->Display(1);
Active->Display();
Active = Helper;
Active->SetBorder(Config.active_window_border);
Active->Display();
@@ -646,7 +646,7 @@ void __deal_with_filenames(SongList &v)
Active->Display();
Active = Main;
Active->SetBorder(Config.active_window_border);
Active->Display(1);
Active->Display();
}
}
}

View File

@@ -20,26 +20,59 @@
#include "window.h"
Window::Window(int startx, int starty, int width, int height, const string &title, Color color, Border border) :
itsWindow(0),
itsWinBorder(0),
itsGetStringHelper(0),
itsStartX(startx),
itsStartY(starty),
itsWidth(width),
itsHeight(height),
itsWindowTimeout(-1),
BBEnabled(1),
AutoRefreshEnabled(1),
itsTitle(title),
itsColor(color),
itsBaseColor(color),
itsBgColor(clDefault),
itsBaseBgColor(clDefault),
itsBorder(border)
void InitScreen()
{
if (itsStartX < 0) itsStartX = 0;
if (itsStartY < 0) itsStartY = 0;
setlocale(LC_ALL, "");
initscr();
if (has_colors())
{
start_color();
use_default_colors();
int num = 1;
for (int i = -1; i < 8; i++)
for (int j = 0; j < 8; j++)
init_pair(num++, j, i);
}
noecho();
cbreak();
curs_set(0);
}
void DestroyScreen()
{
curs_set(1);
endwin();
}
Window::Window(size_t startx,
size_t starty,
size_t width,
size_t height,
const string &title,
Color color,
Border border)
: itsWindow(0),
itsWinBorder(0),
itsGetStringHelper(0),
itsStartX(startx),
itsStartY(starty),
itsWidth(width),
itsHeight(height),
itsWindowTimeout(-1),
itsX(0),
itsY(0),
itsTitle(title),
itsColor(color),
itsBaseColor(color),
itsBgColor(clDefault),
itsBaseBgColor(clDefault),
itsBorder(border)
{
if (itsStartX > size_t(COLS)
|| itsStartY > size_t(LINES)
|| itsWidth+itsStartX > size_t(COLS)
|| itsHeight+itsStartY > size_t(LINES))
throw BadSize();
if (itsBorder != brNone)
{
@@ -57,10 +90,7 @@ Window::Window(int startx, int starty, int width, int height, const string &titl
itsHeight -= 2;
}
if (itsWidth > 0 && itsHeight > 0)
itsWindow = newwin(itsHeight, itsWidth, itsStartY, itsStartX);
else
itsWindow = newwin(0, 0, 0, 0);
itsWindow = newwin(itsHeight, itsWidth, itsStartY, itsStartX);
SetColor(itsColor);
keypad(itsWindow, 1);
@@ -71,12 +101,13 @@ Window::Window(const Window &w)
itsWindow = dupwin(w.itsWindow);
itsWinBorder = dupwin(w.itsWinBorder);
itsGetStringHelper = w.itsGetStringHelper;
itsWindowTimeout = w.itsWindowTimeout;
itsX = w.itsX;
itsY = w.itsY;
itsStartX = w.itsStartX;
itsStartY = w.itsStartY;
itsWidth = w.itsWidth;
itsHeight = w.itsHeight;
BBEnabled = w.BBEnabled;
AutoRefreshEnabled = w.AutoRefreshEnabled;
itsTitle = w.itsTitle;
itsColors = w.itsColors;
itsColor = w.itsColor;
@@ -84,6 +115,8 @@ Window::Window(const Window &w)
itsBgColor = w.itsBgColor;
itsBaseBgColor = w.itsBaseBgColor;
itsBorder = w.itsBorder;
SetColor(itsColor, itsBgColor);
keypad(itsWindow, 1);
}
Window::~Window()
@@ -230,13 +263,13 @@ void Window::ShowBorder() const
refresh();
}
void Window::Display(bool stub)
void Window::Display()
{
ShowBorder();
Refresh(stub);
Refresh();
}
void Window::Refresh(bool)
void Window::Refresh()
{
wrefresh(itsWindow);
}
@@ -269,11 +302,6 @@ void Window::AltCharset(bool alt) const
alt ? wattron(itsWindow, A_ALTCHARSET) : wattroff(itsWindow, A_ALTCHARSET);
}
void Window::Delay(bool delay) const
{
nodelay(itsWindow, !delay);
}
void Window::SetTimeout(int timeout)
{
itsWindowTimeout = timeout;
@@ -292,145 +320,17 @@ void Window::ReadKey() const
void Window::Write(int limit, const string &str, bool clrtoeol)
{
if (BBEnabled)
{
bool collect = false;
string color, tmp;
for (string::const_iterator it = str.begin(); it != str.end() && limit > 0; it++)
{
if (*it == '[' && (*(it+1) == '.' || *(it+1) == '/'))
collect = 1;
if (!collect)
{
tmp += *it;
limit--;
}
else
{
if (*it != '[')
{
color += *it;
if (color.length() > 10) collect = 0; // longest bbcode is 10 chars long
}
else
{
limit -= color.length();
tmp += color;
color = *it;
}
}
if (*it == ']' || it+1 == str.end())
collect = 0;
if (!collect && !color.empty())
{
waddstr(itsWindow,tmp.c_str());
tmp.clear();
if (isdigit(color[2]))
{
int x, y;
getyx(itsWindow, y, x);
Coordinates coords = IntoCoordinates(color);
wmove(itsWindow, coords.second == -1 ? y : coords.second, coords.first);
limit -= coords.first-x;
}
else if (IsValidColor(color))
{
ColorPair colors = IntoColor(color);
SetColor(colors.first, colors.second);
}
else
{
limit -= color.length();
tmp += limit > 0 ? color : color.substr(0, color.length()+limit);
}
color.clear();
}
}
if (!tmp.empty()) waddstr(itsWindow,tmp.c_str());
}
else
waddstr(itsWindow,str.c_str());
waddstr(itsWindow,str.c_str());
if (clrtoeol)
wclrtoeol(itsWindow);
if (AutoRefreshEnabled)
wrefresh(itsWindow);
}
#ifdef UTF8_ENABLED
#ifdef _UTF8
void Window::Write(int limit, const wstring &str, bool clrtoeol)
{
if (BBEnabled)
{
bool collect = false;
wstring color, tmp;
for (wstring::const_iterator it = str.begin(); it != str.end() && limit > 0; it++)
{
if (*it == '[' && (*(it+1) == '.' || *(it+1) == '/'))
collect = 1;
if (!collect)
{
tmp += *it;
limit -= wcwidth(*it);
}
else
{
if (*it != '[')
{
color += *it;
if (color.length() > 10) collect = 0; // longest bbcode is 10 chars long
}
else
{
limit -= Length(color);
tmp += color;
color = *it;
}
}
if (*it == ']' || it+1 == str.end())
collect = 0;
if (!collect && !color.empty())
{
wprintw(itsWindow, "%ls", tmp.c_str());
tmp.clear();
if (isdigit(color[2]))
{
int x, y;
getyx(itsWindow, y, x);
Coordinates coords = IntoCoordinates(ToString(color));
wmove(itsWindow, coords.second < 0 ? y : coords.second, coords.first);
limit -= coords.first-x;
}
else if (IsValidColor(ToString(color)))
{
ColorPair colors = IntoColor(ToString(color));
SetColor(colors.first, colors.second);
}
else
{
limit -= Length(color);
tmp += limit > 0 ? color : color.substr(0, color.length()+limit);
}
color.clear();
}
}
if (!tmp.empty()) wprintw(itsWindow, "%ls", tmp.c_str());
}
else
wprintw(itsWindow, "%ls", str.c_str());
wprintw(itsWindow, "%ls", str.c_str());
if (clrtoeol)
wclrtoeol(itsWindow);
if (AutoRefreshEnabled)
wrefresh(itsWindow);
}
void Window::WriteXY(int x, int y, int limit, const wstring &str, bool cleartoeol)
@@ -446,20 +346,20 @@ void Window::WriteXY(int x, int y, int limit, const string &str, bool cleartoeol
Write(limit, str, cleartoeol);
}
string Window::GetString(const string &base, unsigned int length, int width) const
string Window::GetString(const string &base, size_t length, size_t width) const
{
int input, beginning, maxbeginning, minx, x, y, maxx;
int input;
size_t beginning, maxbeginning, minx, x, y, maxx;
getyx(itsWindow, y, x);
minx = maxx = x;
width--;
if (width == -1)
if (width == size_t(-1))
width = itsWidth-x-1;
if (width < 0)
return "";
curs_set(1);
wstring tmp = ToWString(base);
std::wstring tmp = ToWString(base);
string tmp_in;
wchar_t wc_in;
@@ -570,26 +470,41 @@ string Window::GetString(const string &base, unsigned int length, int width) con
}
while (input != 10);
curs_set(0);
return ToString(tmp);
}
void Window::GetXY(int &x, int &y)
{
getyx(itsWindow, y, x);
itsX = x;
itsY = y;
}
void Window::GotoXY(int x, int y)
{
wmove(itsWindow, y, x);
itsX = x;
itsY = y;
}
const int &Window::X() const
{
return itsX;
}
const int &Window::Y() const
{
return itsY;
}
void Window::Scrollable(bool scrollable) const
{
scrollok(itsWindow, scrollable);
idlok(itsWindow, scrollable);
}
void Window::GetXY(int &x, int &y) const
{
getyx(itsWindow, y, x);
}
void Window::GotoXY(int x, int y) const
{
wmove(itsWindow, y, x);
}
int Window::GetWidth() const
size_t Window::GetWidth() const
{
if (itsBorder != brNone)
return itsWidth+2;
@@ -597,9 +512,9 @@ int Window::GetWidth() const
return itsWidth;
}
int Window::GetHeight() const
size_t Window::GetHeight() const
{
int height = itsHeight;
size_t height = itsHeight;
if (itsBorder != brNone)
height += 2;
if (!itsTitle.empty())
@@ -607,7 +522,7 @@ int Window::GetHeight() const
return height;
}
int Window::GetStartX() const
size_t Window::GetStartX() const
{
if (itsBorder != brNone)
return itsStartX-1;
@@ -615,9 +530,9 @@ int Window::GetStartX() const
return itsStartX;
}
int Window::GetStartY() const
size_t Window::GetStartY() const
{
int starty = itsStartY;
size_t starty = itsStartY;
if (itsBorder != brNone)
starty--;
if (!itsTitle.empty())
@@ -625,7 +540,7 @@ int Window::GetStartY() const
return starty;
}
string Window::GetTitle() const
const string &Window::GetTitle() const
{
return itsTitle;
}
@@ -640,186 +555,216 @@ Border Window::GetBorder() const
return itsBorder;
}
void Window::EnableColors()
void Window::Scroll(Where where)
{
if (has_colors())
idlok(itsWindow, 1);
scrollok(itsWindow, 1);
switch (where)
{
start_color();
use_default_colors();
int num = 1;
for (int i = -1; i < 8; i++)
for (int j = 0; j < 8; j++)
init_pair(num++, j, i);
case wUp:
wscrl(itsWindow, 1);
break;
case wDown:
wscrl(itsWindow, -1);
break;
case wPageUp:
wscrl(itsWindow, itsWidth);
break;
case wPageDown:
wscrl(itsWindow, -itsWidth);
break;
default:
break;
}
idlok(itsWindow, 0);
scrollok(itsWindow, 0);
}
Window &Window::operator<<(const Colors &colors)
{
if (colors.fg == clEnd || colors.bg == clEnd)
return *this;
itsColors.push(colors);
SetColor(colors.fg, colors.bg);
return *this;
}
Window &Window::operator<<(const Color &color)
{
switch (color)
{
case clDefault:
while (!itsColors.empty())
itsColors.pop();
SetColor(itsBaseColor, itsBaseBgColor);
break;
case clEnd:
if (!itsColors.empty())
itsColors.pop();
if (!itsColors.empty())
SetColor(itsColors.top().fg, itsColors.top().bg);
else
SetColor(itsBaseColor, itsBaseBgColor);
break;
default:
itsColors.push(Colors(color, clDefault));
SetColor(itsColors.top().fg, itsColors.top().bg);
}
return *this;
}
Window &Window::operator<<(const Format &format)
{
switch (format)
{
case fmtNone:
Bold(0);
Reverse(0);
AltCharset(0);
break;
case fmtBold:
Bold(1);
break;
case fmtBoldEnd:
Bold(0);
break;
case fmtReverse:
Reverse(1);
break;
case fmtReverseEnd:
Reverse(0);
break;
case fmtAltCharset:
AltCharset(1);
break;
case fmtAltCharsetEnd:
AltCharset(0);
break;
}
return *this;
}
Window &Window::operator<<(const XY &coords)
{
GotoXY(coords.x, coords.y);
return *this;
}
Window &Window::operator<<(const char *s)
{
wprintw(itsWindow, "%s", s);
return *this;
}
Window &Window::operator<<(const char &c)
{
wprintw(itsWindow, "%c", c);
return *this;
}
Window &Window::operator<<(const wchar_t *ws)
{
wprintw(itsWindow, "%ls", ws);
return *this;
}
Window &Window::operator<<(const wchar_t &wc)
{
wprintw(itsWindow, "%lc", wc);
return *this;
}
Window &Window::operator<<(const int &i)
{
wprintw(itsWindow, "%d", i);
return *this;
}
Window &Window::operator<<(const double &d)
{
wprintw(itsWindow, "%f", d);
return *this;
}
Window &Window::operator<<(const string &s)
{
wprintw(itsWindow, "%s", s.c_str());
return *this;
}
Window &Window::operator<<(const wstring &ws)
{
for (wstring::const_iterator it = ws.begin(); it != ws.end(); it++)
wprintw(itsWindow, "%lc", *it);
return *this;
}
Window &Window::operator<<(const size_t &s)
{
wprintw(itsWindow, "%u", s);
return *this;
}
Window * Window::EmptyClone() const
{
return new Window(GetStartX(),GetStartY(),GetWidth(),GetHeight(),itsTitle,itsBaseColor,itsBorder);
return new Window(GetStartX(), GetStartY(), GetWidth(), GetHeight(), itsTitle, itsBaseColor, itsBorder);
}
/*char * ToString(const wchar_t *ws)
char *ToString(const wchar_t *ws)
{
string s;
for (int i = 0; i < wcslen(ws); i++)
{
char *c = new char[MB_CUR_MAX+1]();
if (wctomb(c, ws[i]) > 0)
s += c;
delete [] c;
}
char *result = strdup(s.c_str());
return result;
mbstate_t mbs;
memset(&mbs, 0, sizeof(mbs));
size_t len = wcsrtombs(NULL, &ws, 0, &mbs);
if (len == size_t(-1))
return 0;
char *s = new char[len+1]();
wcsrtombs(s, &ws, len, &mbs);
s[len] = 0;
return s;
}
wchar_t * ToWString(const char *s)
wchar_t *ToWString(const char *s)
{
wchar_t *ws = new wchar_t[strlen(s)+1]();
mbstowcs(ws, s, strlen(s));
mbstate_t mbs;
memset(&mbs, 0, sizeof(mbs));
size_t len = mbsrtowcs(NULL, &s, 0, &mbs);
if (len == size_t(-1))
return 0;
wchar_t *ws = new wchar_t[len+1]();
mbsrtowcs(ws, &s, len, &mbs);
ws[len] = 0;
return ws;
}*/
}
string ToString(const wstring &ws)
{
string s;
const wchar_t *c_ws = ws.c_str();
mbstate_t mbs;
memset(&mbs, 0, sizeof(mbs));
int len = wcsrtombs(NULL, &c_ws, 0, &mbs);
if (len <= 0)
return s;
char *c_s = new char[len+1]();
wcsrtombs(c_s, &c_ws, len, &mbs);
c_s[len] = 0;
s = c_s;
delete [] c_s;
return s;
string result;
char *s = ToString(ws.c_str());
if (s)
{
result = s;
delete [] s;
}
return result;
}
wstring ToWString(const string &s)
{
wstring ws;
const char *c_s = s.c_str();
mbstate_t mbs;
memset(&mbs, 0, sizeof(mbs));
int len = mbsrtowcs(NULL, &c_s, 0, &mbs);
if (len <= 0)
return ws;
wchar_t *c_ws = new wchar_t[len+1]();
mbsrtowcs(c_ws, &c_s, len, &mbs);
c_ws[len] = 0;
ws = c_ws;
delete [] c_ws;
return ws;
}
Coordinates Window::IntoCoordinates(const string &s)
{
Coordinates result;
size_t sep = s.find(",");
if (sep != string::npos)
wstring result;
wchar_t *ws = ToWString(s.c_str());
if (ws)
{
result.first = atoi(s.substr(2, sep-2).c_str());
result.second = atoi(s.substr(sep+1).c_str());
}
else
{
result.first = atoi(s.substr(2).c_str());
result.second = -1;
result = ws;
delete [] ws;
}
return result;
}
string Window::OmitBBCodes(const string &str)
{
bool collect = false;
string tmp, color, result;
for (string::const_iterator it = str.begin(); it != str.end(); it++)
{
if (*it == '[' && (*(it+1) == '.' || *(it+1) == '/'))
collect = 1;
if (!collect)
tmp += *it;
else
{
if (*it != '[')
color += *it;
else
{
tmp += color;
color = *it;
}
}
if (*it == ']' || it+1 == str.end())
collect = 0;
if (!collect && !color.empty())
{
result += tmp;
tmp.clear();
if (!isdigit(tmp[2]) && !IsValidColor(color))
tmp += color;
color.clear();
}
}
if (!tmp.empty()) result += tmp;
return result;
}
size_t Window::RealLength(const string &s)
{
if (s.empty())
return 0;
bool collect = false;
int length = 0;
# ifdef UTF8_ENABLED
wstring ws = ToWString(s);
wstring tmp;
# else
const string &ws = s;
string tmp;
# endif
for (int i = 0; i < ws.length(); i++, length++)
{
if (ws[i] == '[' && (ws[i+1] == '.' || ws[i+1] == '/'))
collect = 1;
if (collect)
{
if (ws[i] != '[')
tmp += ws[i];
else
tmp = ws[i];
}
if (ws[i] == ']')
collect = 0;
if (!collect && !tmp.empty())
{
if (isdigit(tmp[2]) || IsValidColor(TO_STRING(tmp)))
{
# ifdef UTF8_ENABLED
length -= Length(tmp);
# else
length -= tmp.length();
# endif
}
tmp.clear();
}
}
return length;
}
size_t Window::Length(const wstring &ws)
{
size_t length = 0;

View File

@@ -33,13 +33,15 @@
#include <cstdlib>
#include <cstring>
#ifdef UTF8_ENABLED
#ifdef _UTF8
# define UNICODE 1
# define my_char_t wchar_t
# define my_string_t wstring
# define TO_STRING(x) ToString(x)
# define TO_WSTRING(x) ToWString(x)
#else
# define UNICODE 0
# define my_char_t char
# define my_string_t string
# define TO_STRING(x) x
# define TO_WSTRING(x) x
@@ -49,70 +51,114 @@ using std::string;
using std::wstring;
using std::vector;
enum Color { clDefault, clBlack, clRed, clGreen, clYellow, clBlue, clMagenta, clCyan, clWhite };
enum Color { clDefault, clBlack, clRed, clGreen, clYellow, clBlue, clMagenta, clCyan, clWhite, clEnd };
enum Format { fmtNone = 100, fmtBold, fmtBoldEnd, fmtReverse, fmtReverseEnd, fmtAltCharset, fmtAltCharsetEnd };
enum Border { brNone, brBlack, brRed, brGreen, brYellow, brBlue, brMagenta, brCyan, brWhite };
enum Where { wUp, wDown, wPageUp, wPageDown, wHome, wEnd };
typedef void (*GetStringHelper)();
typedef std::pair<Color, Color> ColorPair;
typedef std::pair<int, int> Coordinates;
string ToString(const wstring &);
wstring ToWString(const string &);
void InitScreen();
void DestroyScreen();
struct Colors
{
Colors(Color one, Color two = clDefault) : fg(one), bg(two) { }
Color fg;
Color bg;
};
struct XY
{
XY(int xx, int yy) : x(xx), y(yy) { }
int x;
int y;
};
char *ToString(const wchar_t *);
wchar_t *ToWString(const char *);
std::string ToString(const std::wstring &);
std::wstring ToWString(const std::string &);
class Window
{
public:
Window(int, int, int, int, const string &, Color, Border);
Window(size_t, size_t, size_t, size_t, const std::string &, Color, Border);
Window(const Window &);
virtual ~Window();
virtual WINDOW *RawWin() const { return itsWindow; }
virtual void SetGetStringHelper(GetStringHelper helper) { itsGetStringHelper = helper; }
virtual void SetColor(Color, Color = clDefault);
virtual void SetBaseColor(Color, Color = clDefault);
virtual void SetBorder(Border);
virtual void EnableBB() { BBEnabled = 1; }
virtual void DisableBB() { BBEnabled = 0; }
virtual void SetTitle(const string &);
WINDOW *Raw() const { return itsWindow; }
size_t GetWidth() const;
size_t GetHeight() const;
size_t GetStartX() const;
size_t GetStartY() const;
const std::string &GetTitle() const;
Color GetColor() const;
Border GetBorder() const;
std::string GetString(const std::string &, size_t = -1, size_t = 0) const;
string GetString(unsigned int length = -1, int width = 0) const { return GetString("", length, width); }
void GetXY(int &, int &);
void GotoXY(int, int);
const int &X() const;
const int &Y() const;
void SetGetStringHelper(GetStringHelper helper) { itsGetStringHelper = helper; }
void SetColor(Color, Color = clDefault);
void SetBaseColor(Color, Color = clDefault);
void SetBorder(Border);
void SetTimeout(int);
void SetTitle(const string &);
void Hide(char = 32) const;
void Bold(bool) const;
void Reverse(bool) const;
void AltCharset(bool) const;
void Display();
virtual void Refresh();
virtual void MoveTo(int, int);
virtual void Resize(int, int);
virtual void Display(bool = 0);
virtual void Refresh(bool = 0);
virtual void Clear(bool stub = 1);
virtual void Hide(char = 32) const;
virtual void Bold(bool) const;
virtual void Reverse(bool) const;
virtual void AltCharset(bool) const;
virtual void Delay(bool) const;
virtual void SetTimeout(int);
virtual void AutoRefresh(bool val) { AutoRefreshEnabled = val; }
virtual void ReadKey(int &) const;
virtual void ReadKey() const;
virtual void Write(const string &s, bool cte = 0) { Write(0xFFFF, s, cte); }
virtual void Write(int, const string &, bool = 0);
virtual void WriteXY(int x, int y, const string &s, bool ete = 0) { WriteXY(x, y, 0xFFFF, s, ete); }
virtual void WriteXY(int, int, int, const string &, bool = 0);
# ifdef UTF8_ENABLED
virtual void Write(const wstring &s, bool cte = 0) { Write(0xFFFF, s, cte); }
virtual void Write(int, const wstring &, bool = 0);
virtual void WriteXY(int x, int y, const wstring &s, bool ete = 0) { WriteXY(x, y, 0xFFFF, s, ete); }
virtual void WriteXY(int, int, int, const wstring &, bool = 0);
# endif
virtual string GetString(const string &, unsigned int = -1, int = 0) const;
virtual string GetString(unsigned int length = -1, int width = 0) const { return GetString("", length, width); }
virtual void Scrollable(bool) const;
virtual void GetXY(int &, int &) const;
virtual void GotoXY(int, int) const;
virtual int GetWidth() const;
virtual int GetHeight() const;
virtual int GetStartX() const;
virtual int GetStartY() const;
virtual string GetTitle() const;
virtual Color GetColor() const;
virtual Border GetBorder() const;
void ReadKey(int &) const;
void ReadKey() const;
void Write(const string &s, bool cte = 0) { Write(0xFFFF, s, cte); }
void Write(int, const string &, bool = 0);
void WriteXY(int x, int y, const string &s, bool ete = 0) { WriteXY(x, y, 0xFFFF, s, ete); }
void WriteXY(int, int, int, const string &, bool = 0);
# ifdef _UTF8
void Write(const wstring &s, bool cte = 0) { Write(0xFFFF, s, cte); }
void Write(int, const wstring &, bool = 0);
void WriteXY(int x, int y, const wstring &s, bool ete = 0) { WriteXY(x, y, 0xFFFF, s, ete); }
void WriteXY(int, int, int, const wstring &, bool = 0);
# endif
void Scrollable(bool) const;
virtual void Scroll(Where);
Window &operator<<(const Colors &);
Window &operator<<(const Color &);
Window &operator<<(const Format &);
Window &operator<<(const XY &);
Window &operator<<(const char *);
Window &operator<<(const char &);
Window &operator<<(const wchar_t *);
Window &operator<<(const wchar_t &);
Window &operator<<(const int &);
Window &operator<<(const double &);
Window &operator<<(const size_t &);
Window &operator<<(const std::string &);
Window &operator<<(const std::wstring &);
virtual Window *Clone() const { return new Window(*this); }
virtual Window *EmptyClone() const;
virtual Window * Clone() const { return new Window(*this); }
virtual Window * EmptyClone() const;
// stubs for inherits, ugly shit, needs improvement
virtual void Select(int, bool) { }
@@ -123,38 +169,40 @@ class Window
virtual bool IsStatic(int = -1) const { return 0; }
virtual void Highlight(int) { }
virtual string GetOption(int = -1) const { return ""; }
virtual void Go(Where) { } // for Menu and Scrollpad class
virtual int GetChoice() const { return -1; } // for Menu class
virtual void Add(string str) { Write(str); } // for Scrollpad class
//virtual void Add(string str) { Write(str); } // for Scrollpad class
static void EnableColors();
static Coordinates IntoCoordinates(const string &);
static bool IsValidColor(const string &);
static string OmitBBCodes(const string &);
static size_t RealLength(const string &);
static size_t Length(const string &s) { return Length(ToWString(s)); }
static size_t Length(const wstring &);
protected:
class BadSize { };
virtual void Recreate();
virtual void ShowBorder() const;
virtual ColorPair IntoColor(const string &);
WINDOW *itsWindow;
WINDOW *itsWinBorder;
GetStringHelper itsGetStringHelper;
int itsStartX;
int itsStartY;
int itsWidth;
int itsHeight;
size_t itsStartX;
size_t itsStartY;
size_t itsWidth;
size_t itsHeight;
int itsWindowTimeout;
bool BBEnabled;
bool AutoRefreshEnabled;
int itsX;
int itsY;
string itsTitle;
std::stack<ColorPair> itsColors;
std::stack<Colors> itsColors;
Color itsColor;
Color itsBaseColor;
Color itsBgColor;
Color itsBaseBgColor;
Border itsBorder;
};