repo starts

This commit is contained in:
unknown
2008-08-04 22:20:45 +02:00
commit 6315a6c7ec
25 changed files with 5337 additions and 0 deletions

11
src/Makefile.am Normal file
View File

@@ -0,0 +1,11 @@
bin_PROGRAMS = ncmpcpp
ncmpcpp_SOURCES = color_parser.cpp helpers.cpp menu.cpp misc.cpp ncmpcpp.cpp \
scrollpad.cpp settings.cpp song.cpp status_checker.cpp window.cpp
# set the include path found by configure
INCLUDES= $(all_includes)
# the library search path.
ncmpcpp_LDFLAGS = $(all_libraries)
noinst_HEADERS = helpers.h menu.h scrollpad.h settings.h song.h \
status_checker.h window.h

547
src/color_parser.cpp Normal file
View File

@@ -0,0 +1,547 @@
/***************************************************************************
* 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 "window.h"
const COLOR * Window::into_color(const string &str) const
{
COLOR *colors = new COLOR[2];
if (str == "[/]")
{
Bold(0);
Reverse(0);
AltCharset(0);
colors[0] = itsBaseColor;
colors[1] = itsBaseBgColor;
return colors;
}
if (str[1] == '/')
{
if (str == "[/a]")
AltCharset(0);
if (str == "[/b]")
Bold(0);
if (str == "[/r]")
Reverse(0);
if (str.length() > 4) // /green etc.
{
colors[0] = itsBaseColor;
colors[1] = itsBaseBgColor;
return colors;
}
colors[0] = itsColor;
colors[1] = itsBgColor;
return colors;
}
else
{
if (str == "[a]") AltCharset(1);
if (str == "[b]") Bold(1);
if (str == "[r]") Reverse(1);
if (str.length() <= 3)
{
colors[0] = itsColor;
colors[1] = itsBgColor;
}
if (str == "[red]")
{
colors[0] = clRed;
colors[1] = itsBaseBgColor;
}
if (str == "[black]")
{
colors[0] = clBlack;
colors[1] = itsBaseBgColor;
}
if (str == "[blue]")
{
colors[0] = clBlue;
colors[1] = itsBaseBgColor;
}
if (str == "[green]")
{
colors[0] = clGreen;
colors[1] = itsBaseBgColor;
}
if (str == "[yellow]")
{
colors[0] = clYellow;
colors[1] = itsBaseBgColor;
}
if (str == "[magenta]")
{
colors[0] = clMagenta;
colors[1] = itsBaseBgColor;
}
if (str == "[cyan]")
{
colors[0] = clCyan;
colors[1] = itsBaseBgColor;
}
if (str == "[white]")
{
colors[0] = clWhite;
colors[1] = itsBaseBgColor;
}
/*if (str == "[black_red]")
{
colors[0] = clBlack;
colors[1] = clRed;
}
if (str == "[black_blue]")
{
colors[0] = clBlack;
colors[1] = clBlue;
}
if (str == "[black_green]")
{
colors[0] = clBlack;
colors[1] = clGreen;
}
if (str == "[black_yellow]")
{
colors[0] = clBlack;
colors[1] = clYellow;
}
if (str == "[black_magenta]")
{
colors[0] = clBlack;
colors[1] = clMagenta;
}
if (str == "[black_cyan]")
{
colors[0] = clBlack;
colors[1] = clCyan;
}
if (str == "[black_white]")
{
colors[0] = clBlack;
colors[1] = clWhite;
}
if (str == "[red_black]")
{
colors[0] = clRed;
colors[1] = clBlack;
}
if (str == "[red_blue]")
{
colors[0] = clRed;
colors[1] = clBlue;
}
if (str == "[red_green]")
{
colors[0] = clRed;
colors[1] = clGreen;
}
if (str == "[red_yellow]")
{
colors[0] = clRed;
colors[1] = clYellow;
}
if (str == "[red_magenta]")
{
colors[0] = clRed;
colors[1] = clMagenta;
}
if (str == "[red_cyan]")
{
colors[0] = clRed;
colors[1] = clCyan;
}
if (str == "[red_white]")
{
colors[0] = clRed;
colors[1] = clWhite;
}
if (str == "[red_white]")
{
colors[0] = clRed;
colors[1] = clWhite;
}
if (str == "[blue_black]")
{
colors[0] = clBlue;
colors[1] = clBlack;
}
if (str == "[blue_red]")
{
colors[0] = clBlue;
colors[1] = clRed;
}
if (str == "[blue_green]")
{
colors[0] = clBlue;
colors[1] = clGreen;
}
if (str == "[blue_yellow]")
{
colors[0] = clBlue;
colors[1] = clYellow;
}
if (str == "[blue_magenta]")
{
colors[0] = clBlue;
colors[1] = clMagenta;
}
if (str == "[blue_cyan]")
{
colors[0] = clBlue;
colors[1] = clCyan;
}
if (str == "[blue_white]")
{
colors[0] = clBlue;
colors[1] = clWhite;
}
if (str == "[green_black]")
{
colors[0] = clGreen;
colors[1] = clBlack;
}
if (str == "[green_red]")
{
colors[0] = clGreen;
colors[1] = clRed;
}
if (str == "[green_blue]")
{
colors[0] = clGreen;
colors[1] = clBlue;
}
if (str == "[green_yellow]")
{
colors[0] = clGreen;
colors[1] = clYellow;
}
if (str == "[green_magenta]")
{
colors[0] = clGreen;
colors[1] = clMagenta;
}
if (str == "[green_cyan]")
{
colors[0] = clGreen;
colors[1] = clCyan;
}
if (str == "[green_white]")
{
colors[0] = clGreen;
colors[1] = clWhite;
}
if (str == "[yellow_black]")
{
colors[0] = clYellow;
colors[1] = clBlack;
}
if (str == "[yellow_red]")
{
colors[0] = clYellow;
colors[1] = clRed;
}
if (str == "[yellow_blue]")
{
colors[0] = clYellow;
colors[1] = clBlue;
}
if (str == "[yellow_green]")
{
colors[0] = clYellow;
colors[1] = clGreen;
}
if (str == "[yellow_magenta]")
{
colors[0] = clYellow;
colors[1] = clMagenta;
}
if (str == "[yellow_cyan]")
{
colors[0] = clYellow;
colors[1] = clCyan;
}
if (str == "[yellow_white]")
{
colors[0] = clYellow;
colors[1] = clWhite;
}
if (str == "[magenta_black]")
{
colors[0] = clMagenta;
colors[1] = clBlack;
}
if (str == "[magenta_red]")
{
colors[0] = clMagenta;
colors[1] = clRed;
}
if (str == "[magenta_blue]")
{
colors[0] = clMagenta;
colors[1] = clBlue;
}
if (str == "[magenta_green]")
{
colors[0] = clMagenta;
colors[1] = clGreen;
}
if (str == "[magenta_yellow]")
{
colors[0] = clMagenta;
colors[1] = clYellow;
}
if (str == "[magenta_cyan]")
{
colors[0] = clMagenta;
colors[1] = clCyan;
}
if (str == "[magenta_white]")
{
colors[0] = clMagenta;
colors[1] = clWhite;
}
if (str == "[cyan_black]")
{
colors[0] = clCyan;
colors[1] = clBlack;
}
if (str == "[cyan_red]")
{
colors[0] = clCyan;
colors[1] = clRed;
}
if (str == "[cyan_blue]")
{
colors[0] = clCyan;
colors[1] = clBlue;
}
if (str == "[cyan_green]")
{
colors[0] = clCyan;
colors[1] = clGreen;
}
if (str == "[cyan_yellow]")
{
colors[0] = clCyan;
colors[1] = clYellow;
}
if (str == "[cyan_magenta]")
{
colors[0] = clCyan;
colors[1] = clMagenta;
}
if (str == "[cyan_white]")
{
colors[0] = clCyan;
colors[1] = clWhite;
}
if (str == "[white_black]")
{
colors[0] = clWhite;
colors[1] = clBlack;
}
if (str == "[white_red]")
{
colors[0] = clWhite;
colors[1] = clRed;
}
if (str == "[white_blue]")
{
colors[0] = clWhite;
colors[1] = clBlue;
}
if (str == "[white_green]")
{
colors[0] = clWhite;
colors[1] = clGreen;
}
if (str == "[white_yellow]")
{
colors[0] = clWhite;
colors[1] = clYellow;
}
if (str == "[white_magenta]")
{
colors[0] = clWhite;
colors[1] = clMagenta;
}
if (str == "[white_cyan]")
{
colors[0] = clWhite;
colors[1] = clCyan;
}*/
}
return colors;
}
bool is_valid_color(const string &str)
{
return str == "[/]" ||
str == "[b]" ||
str == "[/b]" ||
str == "[r]" ||
str == "[/r]" ||
str == "[a]" ||
str == "[/a]" ||
str == "[black]" ||
str == "[/black]" ||
str == "[red]" ||
str == "[/red]" ||
str == "[blue]" ||
str == "[/blue]" ||
str == "[green]" ||
str == "[/green]" ||
str == "[yellow]" ||
str == "[/yellow]" ||
str == "[magenta]" ||
str == "[/magenta]" ||
str == "[cyan]" ||
str == "[/cyan]" ||
str == "[white]" ||
str == "[/white]";
/*str == "[black_red]"||
str == "[/black_red]" ||
str == "[black_blue]"||
str == "[/black_blue]" ||
str == "[black_green]"||
str == "[/black_green]" ||
str == "[black_yellow]"||
str == "[/black_yellow]" ||
str == "[black_magenta]"||
str == "[/black_magenta]" ||
str == "[black_cyan]"||
str == "[/black_cyan]" ||
str == "[black_white]"||
str == "[/black_white]" ||
str == "[red_black]"||
str == "[/red_black]" ||
str == "[red_blue]"||
str == "[/red_blue]" ||
str == "[red_green]"||
str == "[/red_green]" ||
str == "[red_yellow]"||
str == "[/red_yellow]" ||
str == "[red_magenta]"||
str == "[/red_magenta]" ||
str == "[red_cyan]"||
str == "[/red_cyan]" ||
str == "[red_white]"||
str == "[/red_white]" ||
str == "[blue_black]"||
str == "[/blue_black]" ||
str == "[blue_red]"||
str == "[/blue_red]" ||
str == "[blue_green]"||
str == "[/blue_green]" ||
str == "[blue_yellow]"||
str == "[/blue_yellow]" ||
str == "[blue_magenta]"||
str == "[/blue_magenta]" ||
str == "[blue_cyan]"||
str == "[/blue_cyan]" ||
str == "[blue_white]"||
str == "[/blue_white]" ||
str == "[green_black]"||
str == "[/green_black]" ||
str == "[green_red]"||
str == "[/green_red]" ||
str == "[green_blue]"||
str == "[/green_blue]" ||
str == "[green_yellow]"||
str == "[/green_yellow]" ||
str == "[green_magenta]"||
str == "[/green_magenta]" ||
str == "[green_cyan]"||
str == "[/green_cyan]" ||
str == "[green_white]"||
str == "[/green_white]" ||
str == "[yellow_black]"||
str == "[/yellow_black]" ||
str == "[yellow_red]"||
str == "[/yellow_red]" ||
str == "[yellow_blue]"||
str == "[/yellow_blue]" ||
str == "[yellow_green]"||
str == "[/yellow_green]" ||
str == "[yellow_magenta]"||
str == "[/yellow_magenta]" ||
str == "[yellow_cyan]"||
str == "[/yellow_cyan]" ||
str == "[yellow_white]"||
str == "[/yellow_white]" ||
str == "[magenta_black]"||
str == "[/magenta_black]" ||
str == "[magenta_red]"||
str == "[/magenta_red]" ||
str == "[magenta_blue]"||
str == "[/magenta_blue]" ||
str == "[magenta_green]"||
str == "[/magenta_green]" ||
str == "[magenta_yellow]"||
str == "[/magenta_yellow]" ||
str == "[magenta_cyan]"||
str == "[/magenta_cyan]" ||
str == "[magenta_white]"||
str == "[/magenta_white]" ||
str == "[cyan_black]"||
str == "[/cyan_black]" ||
str == "[cyan_red]"||
str == "[/cyan_red]" ||
str == "[cyan_blue]"||
str == "[/cyan_blue]" ||
str == "[cyan_green]"||
str == "[/cyan_green]" ||
str == "[cyan_yellow]"||
str == "[/cyan_yellow]" ||
str == "[cyan_magenta]"||
str == "[/cyan_magenta]" ||
str == "[cyan_white]"||
str == "[/cyan_white]" ||
str == "[white_black]"||
str == "[/white_black]" ||
str == "[white_red]"||
str == "[/white_red]" ||
str == "[white_blue]"||
str == "[/white_blue]" ||
str == "[white_green]"||
str == "[/white_green]" ||
str == "[white_yellow]"||
str == "[/white_yellow]" ||
str == "[white_magenta]"||
str == "[/white_magenta]" ||
str == "[white_cyan]"||
str == "[/white_cyan]";*/
}

482
src/helpers.cpp Normal file
View File

@@ -0,0 +1,482 @@
/***************************************************************************
* 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 "helpers.h"
#include "settings.h"
#define FOR_EACH_MPD_DATA(x) for (; (x); (x) = mpd_data_get_next(x))
extern MpdObj *conn;
extern MpdData *browser;
extern ncmpcpp_config Config;
extern Menu *mBrowser;
extern Menu *mTagEditor;
extern Menu *mSearcher;
extern Window *wFooter;
extern vector<Song> vPlaylist;
extern vector<MpdDataType> vFileType;
extern vector<string> vNameList;
extern Song edited_song;
extern Song searched_song;
extern int block_statusbar_update_delay;
extern int browsed_dir_scroll_begin;
extern time_t block_delay;
extern string browsed_dir;
extern string browsed_subdir;
extern bool messages_allowed;
extern bool block_progressbar_update;
extern bool block_statusbar_update;
extern bool search_case_sensitive;
extern bool search_mode_match;
extern string EMPTY;
extern string UNKNOWN_ARTIST;
extern string UNKNOWN_TITLE;
extern string UNKNOWN_ALBUM;
void WindowTitle(const string &status)
{
if (TERMINAL_TYPE != "linux" && Config.set_window_title)
printf("\033]0;%s\7",status.c_str());
}
string DisplaySong(const Song &s, const string &song_template)
{
string result;
bool link_tags = 0;
bool tags_present = 0;
int i = 0;
for (string::const_iterator it = song_template.begin(); it != song_template.end(); it++)
{
if (*it == '}')
{
if (!tags_present)
result = result.substr(0, result.length()-i);
it++;
link_tags = 0;
i = 0;
if (*it == '|' && *(it+1) == '{')
{
if (!tags_present)
it++;
else
while (*it++ != '}');
}
}
if (*it == '{')
{
i = 0;
tags_present = 1;
link_tags = 1;
it++;
}
if (it == song_template.end())
break;
if (*it != '%')
{
i++;
result += *it;
}
else
{
switch (*++it)
{
case 'l':
{
result += s.GetLength();
break;
}
case 'F':
{
result += s.GetFile();
break;
}
case 'f':
{
result += s.GetShortFilename();
break;
}
case 'a':
{
if (link_tags)
{
if (s.GetArtist() != UNKNOWN_ARTIST)
result += s.GetArtist();
else
tags_present = 0;
}
else
result += s.GetArtist();
break;
}
case 'b':
{
if (link_tags)
{
if (s.GetAlbum() != UNKNOWN_ALBUM)
result += s.GetAlbum();
else
tags_present = 0;
}
else
result += s.GetAlbum();
break;
}
case 'y':
{
if (link_tags)
{
if (s.GetYear() != EMPTY)
result += s.GetYear();
else
tags_present = 0;
}
else
result += s.GetYear();
break;
}
case 'n':
{
if (link_tags)
{
if (s.GetTrack() != EMPTY)
result += s.GetTrack();
else
tags_present = 0;
}
else
result += s.GetTrack();
break;
}
case 'g':
{
if (link_tags)
{
if (s.GetGenre() != EMPTY)
result += s.GetGenre();
else
tags_present = 0;
}
else
result += s.GetGenre();
break;
}
case 'c':
{
if (link_tags)
{
if (s.GetComment() != EMPTY)
result += s.GetComment();
else
tags_present = 0;
}
else
result += s.GetComment();
break;
}
case 't':
{
if (link_tags)
{
if (s.GetTitle() != UNKNOWN_TITLE)
result += s.GetTitle();
else
tags_present = 0;
}
else
result += s.GetTitle();
break;
}
}
}
}
return result;
}
void PrepareSearchEngine(Song &s)
{
s.Clear();
mSearcher->Clear();
mSearcher->Reset();
mSearcher->AddOption("[b]Filename:[/b] " + s.GetShortFilename());
mSearcher->AddOption("[b]Title:[/b] " + s.GetTitle());
mSearcher->AddOption("[b]Artist:[/b] " + s.GetArtist());
mSearcher->AddOption("[b]Album:[/b] " + s.GetAlbum());
mSearcher->AddOption("[b]Year:[/b] " + s.GetYear());
mSearcher->AddOption("[b]Track:[/b] " + s.GetTrack());
mSearcher->AddOption("[b]Genre:[/b] " + s.GetGenre());
mSearcher->AddOption("[b]Comment:[/b] " + s.GetComment());
mSearcher->AddSeparator();
mSearcher->AddOption("[b]Search mode:[/b] " + (search_mode_match ? search_mode_one : search_mode_two));
mSearcher->AddOption("[b]Case sensitive:[/b] " + (string)(search_case_sensitive ? "Yes" : "No"));
mSearcher->AddSeparator();
mSearcher->AddOption("Search");
mSearcher->AddOption("Reset");
}
void Search(vector<Song> &result, Song &s)
{
result.clear();
if (s.Empty())
return;
MpdData *everything = mpd_database_get_complete(conn);
bool found = 1;
s.GetEmptyFields(1);
if (!search_case_sensitive)
{
string t;
t = s.GetShortFilename();
transform(t.begin(), t.end(), t.begin(), tolower);
s.SetShortFilename(t);
t = s.GetTitle();
transform(t.begin(), t.end(), t.begin(), tolower);
s.SetTitle(t);
t = s.GetArtist();
transform(t.begin(), t.end(), t.begin(), tolower);
s.SetArtist(t);
t = s.GetAlbum();
transform(t.begin(), t.end(), t.begin(), tolower);
s.SetAlbum(t);
t = s.GetGenre();
transform(t.begin(), t.end(), t.begin(), tolower);
s.SetGenre(t);
t = s.GetComment();
transform(t.begin(), t.end(), t.begin(), tolower);
s.SetComment(t);
}
FOR_EACH_MPD_DATA(everything)
{
Song new_song = everything->song;
Song copy = new_song;
if (!search_case_sensitive)
{
string t;
t = copy.GetShortFilename();
transform(t.begin(), t.end(), t.begin(), tolower);
copy.SetShortFilename(t);
t = copy.GetTitle();
transform(t.begin(), t.end(), t.begin(), tolower);
copy.SetTitle(t);
t = copy.GetArtist();
transform(t.begin(), t.end(), t.begin(), tolower);
copy.SetArtist(t);
t = copy.GetAlbum();
transform(t.begin(), t.end(), t.begin(), tolower);
copy.SetAlbum(t);
t = copy.GetGenre();
transform(t.begin(), t.end(), t.begin(), tolower);
copy.SetGenre(t);
t = copy.GetComment();
transform(t.begin(), t.end(), t.begin(), tolower);
copy.SetComment(t);
}
if (search_mode_match)
{
if (found && !s.GetShortFilename().empty())
found = copy.GetShortFilename().find(s.GetShortFilename()) != string::npos;
if (found && !s.GetTitle().empty())
found = copy.GetTitle().find(s.GetTitle()) != string::npos;
if (found && !s.GetArtist().empty())
found = copy.GetArtist().find(s.GetArtist()) != string::npos;
if (found && !s.GetAlbum().empty())
found = copy.GetAlbum().find(s.GetAlbum()) != string::npos;
if (found && !s.GetYear().empty())
found = atoi(copy.GetYear().c_str()) == atoi(s.GetYear().c_str()) && atoi(s.GetYear().c_str());
if (found && !s.GetTrack().empty())
found = atoi(copy.GetTrack().c_str()) == atoi(s.GetTrack().c_str()) && atoi(s.GetTrack().c_str());
if (found && !s.GetGenre().empty())
found = copy.GetGenre().find(s.GetGenre()) != string::npos;
if (found && !s.GetComment().empty())
found = copy.GetComment().find(s.GetComment()) != string::npos;
}
else
{
if (found && !s.GetShortFilename().empty())
found = copy.GetShortFilename() == s.GetShortFilename();
if (found && !s.GetTitle().empty())
found = copy.GetTitle() == s.GetTitle();
if (found && !s.GetArtist().empty())
found = copy.GetArtist() == s.GetArtist();
if (found && !s.GetAlbum().empty())
found = copy.GetAlbum() == s.GetAlbum();
if (found && !s.GetYear().empty())
found = atoi(copy.GetYear().c_str()) == atoi(s.GetYear().c_str()) && atoi(s.GetYear().c_str());
if (found && !s.GetTrack().empty())
found = atoi(copy.GetTrack().c_str()) == atoi(s.GetTrack().c_str()) && atoi(s.GetTrack().c_str());
if (found && !s.GetGenre().empty())
found = copy.GetGenre() == s.GetGenre();
if (found && !s.GetComment().empty())
found = copy.GetComment() == s.GetComment();
}
if (found)
result.push_back(new_song);
found = 1;
}
s.GetEmptyFields(0);
}
void ShowMessage(const string &message, int delay)
{
if (messages_allowed)
{
block_delay = time(NULL);
block_statusbar_update_delay = delay;
block_statusbar_update = 1;
wFooter->Bold(0);
wFooter->WriteXY(0, 1, message, 1);
wFooter->Bold(1);
}
}
bool GetSongInfo(Song &s)
{
mTagEditor->Clear();
mTagEditor->Reset();
string path_to_file = Config.mpd_music_dir + "/" + s.GetFile();
TagLib::FileRef f(path_to_file.c_str());
if (f.isNull())
return false;
s.SetComment(f.tag()->comment().to8Bit(UNICODE));
mTagEditor->AddStaticOption("[b][white]Song name: [green][/b]" + s.GetShortFilename());
mTagEditor->AddStaticOption("[b][white]Location in DB: [green][/b]" + s.GetDirectory());
mTagEditor->AddStaticOption("");
mTagEditor->AddStaticOption("[b][white]Length: [green][/b]" + s.GetLength());
mTagEditor->AddStaticOption("[b][white]Bitrate: [green][/b]" + IntoStr(f.audioProperties()->bitrate()) + " kbps");
mTagEditor->AddStaticOption("[b][white]Sample rate: [green][/b]" + IntoStr(f.audioProperties()->sampleRate()) + " Hz");
mTagEditor->AddStaticOption("[b][white]Channels: [green][/b]" + (string)(f.audioProperties()->channels() == 1 ? "Mono" : "Stereo") + "[/green]");
mTagEditor->AddSeparator();
mTagEditor->AddOption("[b]Title:[/b] " + s.GetTitle());
mTagEditor->AddOption("[b]Artist:[/b] " + s.GetArtist());
mTagEditor->AddOption("[b]Album:[/b] " + s.GetAlbum());
mTagEditor->AddOption("[b]Year:[/b] " + s.GetYear());
mTagEditor->AddOption("[b]Track:[/b] " + s.GetTrack());
mTagEditor->AddOption("[b]Genre:[/b] " + s.GetGenre());
mTagEditor->AddOption("[b]Comment:[/b] " + s.GetComment());
mTagEditor->AddSeparator();
mTagEditor->AddOption("Save");
mTagEditor->AddOption("Cancel");
edited_song = s;
return true;
}
void GetDirectory(string dir)
{
browsed_dir_scroll_begin = 0;
if (browsed_dir != dir)
mBrowser->Reset();
browsed_dir = dir;
vFileType.clear();
vNameList.clear();
mBrowser->Clear();
if (dir != "/")
{
mBrowser->AddOption("[..]");
vFileType.push_back(MPD_DATA_TYPE_DIRECTORY);
vNameList.push_back("");
}
browser = mpd_database_get_directory(conn, (char *)dir.c_str());
FOR_EACH_MPD_DATA(browser)
{
switch (browser->type)
{
case MPD_DATA_TYPE_PLAYLIST:
{
vFileType.push_back(MPD_DATA_TYPE_PLAYLIST);
vNameList.push_back(browser->playlist);
mBrowser->AddOption("[red](playlist)[/red] " + string(browser->playlist));
break;
}
case MPD_DATA_TYPE_DIRECTORY:
{
string subdir = browser->directory;
vFileType.push_back(MPD_DATA_TYPE_DIRECTORY);
if (dir == "/")
vNameList.push_back(subdir.substr(browsed_dir.size()-1,subdir.size()-browsed_dir.size()+1));
else
vNameList.push_back(subdir.substr(browsed_dir.size()+1,subdir.size()-browsed_dir.size()-1));
mBrowser->AddOption("[" + vNameList.back() + "]");
if (vNameList.back() == browsed_subdir)
mBrowser->Highlight(mBrowser->MaxChoice());
break;
}
case MPD_DATA_TYPE_SONG:
{
vFileType.push_back(MPD_DATA_TYPE_SONG);
Song s = browser->song;
vNameList.push_back(s.GetFile());
bool bold = 0;
for (vector<Song>::const_iterator it = vPlaylist.begin(); it != vPlaylist.end(); it++)
if (it->GetFile() == s.GetFile())
bold = 1;
bold ? mBrowser->AddBoldOption(DisplaySong(s)) : mBrowser->AddOption(DisplaySong(s));
break;
}
}
}
mpd_data_free(browser);
browsed_subdir.clear();
}

41
src/helpers.h Normal file
View File

@@ -0,0 +1,41 @@
/***************************************************************************
* 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_HELPERS_H
#define HAVE_HELPERS_H
#include <algorithm>
#include "ncmpcpp.h"
#include "settings.h"
#include "song.h"
extern ncmpcpp_config Config;
void WindowTitle(const string &);
string DisplaySong(const Song &, const string & = Config.song_list_format);
void ShowMessage(const string &, int = Config.message_delay_time);
void GetDirectory(string);
bool GetSongInfo(Song &);
void PrepareSearchEngine(Song &s);
void Search(vector<Song> &, Song &);
#endif

419
src/menu.cpp Normal file
View File

@@ -0,0 +1,419 @@
/***************************************************************************
* 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 "menu.h"
#include "misc.h"
int Menu::count_length(string str)
{
if (str.empty())
return 0;
bool collect = false;
int length = 0;
#ifdef UTF8_ENABLED
wstring str2 = ToWString(str);
wstring tmp;
#else
string &str2 = str;
string tmp;
#endif
for (int i = 0; i < str2.length(); i++, length++)
{
if (str2[i] == '[')
collect = 1;
if (collect)
tmp += str2[i];
if (str2[i] == ']')
collect = 0;
if (!collect && !tmp.empty())
{
if (is_valid_color(TO_STRING(tmp)))
length -= tmp.length();
tmp.clear();
}
}
return length;
}
void Menu::AddOption(const string &str, LOCATION location, HAVE_SEPARATOR separator)
{
itsLocations.push_back(location);
itsOptions.push_back(str);
itsSeparators.push_back(separator);
itsStaticOptions.push_back(0);
itsBold.push_back(0);
}
void Menu::AddBoldOption(const string &str, LOCATION location, HAVE_SEPARATOR separator)
{
itsLocations.push_back(location);
itsOptions.push_back(str);
itsSeparators.push_back(separator);
itsStaticOptions.push_back(0);
itsBold.push_back(1);
}
void Menu::AddStaticOption(const string &str, LOCATION location, HAVE_SEPARATOR separator)
{
itsLocations.push_back(location);
itsOptions.push_back(str);
itsSeparators.push_back(separator);
itsStaticOptions.push_back(1);
itsBold.push_back(0);
itsStaticsNumber++;
}
void Menu::AddStaticBoldOption(const string &str, LOCATION location, HAVE_SEPARATOR separator)
{
itsLocations.push_back(location);
itsOptions.push_back(str);
itsSeparators.push_back(separator);
itsStaticOptions.push_back(1);
itsBold.push_back(1);
itsStaticsNumber++;
}
void Menu::AddSeparator()
{
AddStaticOption("", lLeft, 1);
}
void Menu::UpdateOption(int index, string str, LOCATION location, HAVE_SEPARATOR separator)
{
try
{
itsLocations.at(index-1) = location;
itsOptions.at(index-1) = str;
itsSeparators.at(index-1) = separator;
}
catch (std::out_of_range)
{
}
}
void Menu::BoldOption(int index, IS_BOLD bold)
{
try
{
itsBold.at(index-1) = bold;
}
catch (std::out_of_range)
{
}
}
void Menu::MakeStatic(int index, IS_STATIC stat)
{
try
{
if (stat && !itsStaticOptions.at(index-1))
itsStaticsNumber++;
if (!stat && itsStaticOptions.at(index-1))
itsStaticsNumber--;
itsStaticOptions.at(index-1) = stat;
}
catch (std::out_of_range)
{
}
}
void Menu::DeleteOption(int no)
{
try
{
if (itsStaticOptions.at(no-1))
itsStaticsNumber--;
}
catch (std::out_of_range)
{
return;
}
itsLocations.erase(itsLocations.begin()+no-1);
itsOptions.erase(itsOptions.begin()+no-1);
itsStaticOptions.erase(itsStaticOptions.begin()+no-1);
itsSeparators.erase(itsSeparators.begin()+no-1);
itsBold.erase(itsBold.begin()+no-1);
/*if (itsBeginning > 0 && itsBeginning == itsOptions.size()-itsHeight)
itsBeginning--;
Go(UP);*/
Window::Clear();
}
void Menu::Display()
{
Window::show_border();
Refresh();
}
void Menu::Refresh()
{
if (!itsOptions.empty() && is_static())
if (itsHighlight == 0)
Go(DOWN);
else
Go(UP);
if (MaxChoice() < GetChoice() && !Empty())
Highlight(MaxChoice());
if (itsHighlight > itsBeginning+itsHeight)
Highlight(itsBeginning+itsHeight);
int line = 0;
int last;
if (itsOptions.size() < itsHeight)
last = itsOptions.size();
else
last = itsBeginning+itsHeight;
int check = 0;
bool next = 1;
for (int i = last-1; i > itsBeginning && next; i--)
{
next = 0;
try
{
itsSeparators.at(i);
}
catch (std::out_of_range)
{
check++;
next = 1;
}
}
itsBeginning -= check;
last -= check;
for (int i = itsBeginning; i < last; i++)
{
if (i == itsHighlight && itsHighlightEnabled)
Reverse(1);
if (itsBold[i])
Bold(1);
int ch = itsSeparators[i] ? 0 : 32;
mvwhline(itsWindow,line, 0, ch, itsWidth);
int strlength = itsLocations[i] != lLeft && BBEnabled ? count_length(itsOptions[i]) : itsOptions[i].length();
if (strlength)
{
int x = 0;
if (itsLocations[i] == lCenter)
{
for (; x < (itsWidth-strlength-(!ch ? 4 : 0))/2; x++);
if (!ch)
{
AltCharset(1);
mvwaddstr(itsWindow, line, x, "u ");
AltCharset(0);
x += 2;
}
}
if (itsLocations[i] == lRight)
{
for (; x < (itsWidth-strlength); x++)
if (!ch)
{
AltCharset(1);
mvwaddstr(itsWindow, line, x, "u ");
AltCharset(0);
x += 2;
}
}
WriteXY(x, line, itsOptions[i], 0);
if (!ch && (itsLocations[i] == lCenter || itsLocations[i] == lLeft))
{
x += strlength;
AltCharset(1);
mvwaddstr(itsWindow, line, x, " t");
AltCharset(0);
}
}
line++;
if (i == itsHighlight && itsHighlightEnabled)
Reverse(0);
if (itsBold[i])
Bold(0);
}
wrefresh(itsWindow);
}
void Menu::Go(WHERE where)
{
if (Empty()) return;
int MaxHighlight = itsOptions.size()-1;
int MaxBeginning;
if (itsOptions.size() < itsHeight)
MaxBeginning = 0;
else MaxBeginning = itsOptions.size()-itsHeight;
int MaxCurrentHighlight = itsBeginning+itsHeight-1;
switch (where)
{
case UP:
{
if (itsHighlight <= itsBeginning && itsHighlight > 0) itsBeginning--; // for scrolling
if (itsHighlight == 0)
break;
else
itsHighlight--;
if (is_static())
{
if (itsHighlight == 0)
Go(DOWN);
else
Go(UP);
}
break;
}
case DOWN:
{
if (itsHighlight >= MaxCurrentHighlight && itsHighlight < MaxHighlight) itsBeginning++; // scroll
if (itsHighlight == MaxHighlight)
break;
else
itsHighlight++;
if (is_static())
{
if (itsHighlight == MaxHighlight)
Go(UP);
else
Go(DOWN);
}
break;
}
case PAGE_UP:
{
itsHighlight -= itsHeight;
itsBeginning -= itsHeight;
if (itsBeginning < 0)
{
itsBeginning = 0;
if (itsHighlight < 0) itsHighlight = 0;
}
if (is_static())
{
if (itsHighlight == 0)
Go(DOWN);
else
Go(UP);
}
break;
}
case PAGE_DOWN:
{
itsHighlight += itsHeight;
itsBeginning += itsHeight;
if (itsBeginning > MaxBeginning)
{
itsBeginning = MaxBeginning;
if (itsHighlight > MaxHighlight) itsHighlight = MaxHighlight;
}
if (is_static())
{
if (itsHighlight == MaxHighlight)
Go(UP);
else
Go(DOWN);
}
break;
}
case HOME:
{
itsHighlight = 0;
itsBeginning = 0;
if (is_static())
{
if (itsHighlight == 0)
Go(DOWN);
else
Go(UP);
}
break;
}
case END:
{
itsHighlight = MaxHighlight;
itsBeginning = MaxBeginning;
if (is_static())
{
if (itsHighlight == MaxHighlight)
Go(UP);
else
Go(DOWN);
}
break;
}
}
}
void Menu::Highlight(int which)
{
if (which <= itsOptions.size())
itsHighlight = which-1;
if (which > itsHeight)
itsBeginning = which-itsHeight;
else
itsBeginning = 0;
}
void Menu::Reset()
{
itsHighlight = 0;
itsBeginning = 0;
}
void Menu::Clear(bool clear_screen)
{
itsOptions.clear();
itsStaticOptions.clear();
itsSeparators.clear();
itsLocations.clear();
itsBold.clear();
itsStaticsNumber = 0;
if (clear_screen)
Window::Clear();
}
int Menu::GetRealChoice() const
{
int real_choice = 0;
vector<IS_STATIC>::const_iterator it = itsStaticOptions.begin();
for (int i = 0; i < itsHighlight; it++, i++)
if (!*it) real_choice++;
return real_choice+1;
}
Menu Menu::EmptyClone()
{
return Menu(GetStartX(),GetStartY(),GetWidth(),GetHeight(),itsTitle,itsBaseColor,itsBorder);
}

91
src/menu.h Normal file
View File

@@ -0,0 +1,91 @@
/***************************************************************************
* 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_MENU_H
#define HAVE_MENU_H
#include "window.h"
#include <stdexcept>
typedef bool IS_STATIC;
typedef bool HAVE_SEPARATOR;
typedef bool IS_BOLD;
enum LOCATION { lLeft, lCenter, lRight };
class Menu : public Window
{
public:
Menu(int startx, int starty, int width, int height, string title, COLOR color, BORDER border) : Window(startx, starty, width, height, title, color, border), itsStaticsNumber(0), itsChoice(0), itsBeginning(0), itsHighlight(0), itsHighlightEnabled(1) { SetColor(color); }
virtual ~Menu() {}
virtual void Add(string str) { AddOption(str); }
void AddOption(const string &, LOCATION = lLeft, HAVE_SEPARATOR = 0);
void AddBoldOption(const string &str, LOCATION location = lLeft, HAVE_SEPARATOR sep = 0);
void AddStaticOption(const string &str, LOCATION location = lLeft, HAVE_SEPARATOR sep = 0);
void AddStaticBoldOption(const string &str, LOCATION location = lLeft, HAVE_SEPARATOR sep = 0);
void AddSeparator();
void UpdateOption(int, string, LOCATION = lLeft, HAVE_SEPARATOR = 0);
void BoldOption(int, IS_BOLD);
void MakeStatic(int, IS_STATIC);
void DeleteOption(int);
string GetCurrentOption() { return itsOptions[itsHighlight]; }
string GetOption(int i) { return itsOptions[i-1]; }
virtual void Display();
virtual void Refresh();
virtual void Go(WHERE);
void Highlight(int);
virtual void Reset();
virtual void Clear(bool clear_screen = 1);
void Highlighting(bool hl) { itsHighlightEnabled = hl; }
int GetRealChoice() const;
virtual int GetChoice() const { return itsHighlight+1; }
int MaxChoice() const { return itsOptions.size(); }
int MaxRealChoice() const { return itsOptions.size()-itsStaticsNumber; }
bool Empty() { return itsOptions.empty(); }
Menu EmptyClone();
protected:
vector<string> itsOptions;
vector<IS_STATIC> itsStaticOptions;
vector<HAVE_SEPARATOR> itsSeparators;
vector<LOCATION> itsLocations;
vector<IS_BOLD> itsBold;
int itsStaticsNumber;
int count_length(string);
bool is_static() { return itsStaticOptions[itsHighlight]; }
int itsChoice;
int itsBeginning;
int itsHighlight;
bool itsHighlightEnabled;
};
#endif

69
src/misc.cpp Normal file
View File

@@ -0,0 +1,69 @@
/***************************************************************************
* 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 "misc.h"
using std::stringstream;
int StrToInt(string str)
{
return atoi(str.c_str());
}
int StrToInt(char str[])
{
return atoi(str);
}
string IntoStr(int liczba)
{
stringstream ss;
ss << liczba;
return ss.str();
}
string IntoStr(double liczba, int precision)
{
stringstream ss;
ss << std::fixed << std::setprecision(precision) << liczba;
return ss.str();
}
string ShowTime(int length)
{
stringstream ss;
int minutes = length/60;
length -= minutes*60;
int seconds = length;
ss << minutes << ":";
if (seconds == 0)
{ ss << "00";
return ss.str();
}
if (seconds < 10)
ss << "0" << seconds;
else
ss << seconds;
return ss.str();
}

39
src/misc.h Normal file
View File

@@ -0,0 +1,39 @@
/***************************************************************************
* 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_MISC_H
#define HAVE_MISC_H
#include <cstdlib>
#include <sstream>
#include <iomanip>
#include <string>
using std::string;
int StrToInt(string);
int StrToInt(char);
string IntoStr(int);
string IntoStr(double, int);
string ShowTime(int);
#endif

1170
src/ncmpcpp.cpp Normal file

File diff suppressed because it is too large Load Diff

61
src/ncmpcpp.h Normal file
View File

@@ -0,0 +1,61 @@
/***************************************************************************
* 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_NCMPCPP_H
#define HAVE_NCMPCPP_H
#ifdef UTF8_ENABLED
const bool UNICODE = 1;
# define ncmpcpp_string_t wstring
# define NCMPCPP_TO_WSTRING(x) ToWString(x)
#else
const bool UNICODE = 0;
# define ncmpcpp_string_t string
# define NCMPCPP_TO_WSTRING(x) (x)
#endif
#define ENTER 10
#define KEY_SPACE 32
#include "fileref.h"
#include "tag.h"
#include <libmpd/libmpd.h>
#include <clocale>
#include <ctime>
#include <unistd.h>
#include <vector>
#include "window.h"
#include "menu.h"
#include "scrollpad.h"
#include "misc.h"
enum CurrScreen { csHelp, csPlaylist, csBrowser, csTagEditor, csSearcher };
const int ncmpcpp_window_timeout = 500;
const int search_engine_static_option = 17;
const string TERMINAL_TYPE = getenv("TERM");
const string search_mode_one = "Match if tag contains searched phrase";
const string search_mode_two = "Match only if both values are the same";
#endif

240
src/scrollpad.cpp Normal file
View File

@@ -0,0 +1,240 @@
/***************************************************************************
* 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 "scrollpad.h"
void Scrollpad::Add(string str)
{
if (itsXPos > 0 && str[0] != ' ')
str = " " + str;
itsRawContent += 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;
bool collect = 0;
// no idea why does it work, but it prevents text from going out of the window
// ugly hack, but i didn't come up with anything better
/*if (!itsContent.empty())
for (int i = itsContent.length()-1; itsContent[i] != '\0' && i >= 0; i--)
x++;*/
for (size_t i = 0; i <= s.length(); i++, itsXPos++)
{
if (BBEnabled)
{
if (s[i] == '[')
collect = 1;
if (collect)
tmp += s[i];
if (s[i] == ']' || tmp.length() > 10) // the longest bbcode is 10 chars long
collect = 0;
if (!collect && !tmp.empty())
{
if (is_valid_color(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 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] != ' '))
{
i = space_pos;
itsXPos = x_pos;
s[i] = '\n';
}
}
if (!collect && (itsXPos >= itsWidth || s[i] == '\n'))
{
itsRealHeight++;
itsXPos = 0;
space_pos = 0;
}
}
itsContent += TO_STRING(s);
recreate_win();
}
void Scrollpad::recreate_win()
{
delwin(itsWindow);
itsWindow = newpad(itsRealHeight, itsWidth);
SetColor(itsBaseColor, itsBgColor);
Write(itsContent.c_str());
}
void Scrollpad::Display()
{
Window::show_border();
Refresh();
}
void Scrollpad::Refresh()
{
prefresh(itsWindow,itsBeginning,0,itsStartY,itsStartX,itsStartY+itsHeight-1,itsStartX+itsWidth);
}
void Scrollpad::Resize(int width, int height)
{
if (itsBorder != brNone)
{
delwin(itsWinBorder);
itsWinBorder = newpad(height, width);
wattron(itsWinBorder,COLOR_PAIR(itsBorder));
box(itsWinBorder,0,0);
width -= 2;
height -= 2;
}
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_win();
}
}
void Scrollpad::Go(WHERE where)
{
int MaxBeginning;
if (itsContent.size() < itsHeight)
MaxBeginning = 0;
else
MaxBeginning = itsRealHeight-itsHeight;
switch (where)
{
case UP:
{
if (itsBeginning > 0) itsBeginning--; // for scrolling
break;
}
case DOWN:
{
if (itsBeginning < MaxBeginning) itsBeginning++; // scroll
break;
}
case PAGE_UP:
{
itsBeginning -= itsHeight;
if (itsBeginning < 0) itsBeginning = 0;
break;
}
case PAGE_DOWN:
{
itsBeginning += itsHeight;
if (itsBeginning > MaxBeginning) itsBeginning = MaxBeginning;
break;
}
case HOME:
{
itsBeginning = 0;
break;
}
case END:
{
itsBeginning = MaxBeginning;
break;
}
}
}
void Scrollpad::SetBorder(BORDER border)
{
if (have_to_recreate(border))
recreate_win();
itsBorder = border;
}
void Scrollpad::SetTitle(string newtitle)
{
if (have_to_recreate(newtitle))
recreate_win();
itsTitle = newtitle;
}
void Scrollpad::Clear()
{
itsBeginning = 0;
itsRealHeight = 1;
itsXPos = 0;
itsContent.clear();
itsRawContent.clear();
delwin(itsWindow);
itsWindow = newpad(itsRealHeight, itsWidth);
SetColor(itsColor, itsBgColor);
Window::Clear();
}
Scrollpad Scrollpad::EmptyClone()
{
return Scrollpad(GetStartX(),GetStartY(),GetWidth(),GetHeight(),itsTitle,itsBaseColor,itsBorder);
}
Scrollpad & Scrollpad::operator=(const Scrollpad &base)
{
if (this == &base)
return *this;
itsWindow = base.itsWindow;
itsStartX = base.itsStartX;
itsStartY = base.itsStartY;
itsWidth = base.itsWidth;
itsHeight = base.itsHeight;
itsTitle = base.itsTitle;
itsBorder = base.itsBorder;
itsColor = base.itsColor;
itsContent = base.itsContent;
itsBeginning = base.itsBeginning;
itsRealHeight = base.itsRealHeight;
return *this;
}

54
src/scrollpad.h Normal file
View File

@@ -0,0 +1,54 @@
/***************************************************************************
* 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_SCROLLPAD_H
#define HAVE_SCROLLPAD_H
#include "window.h"
class Scrollpad: public Window
{
public:
Scrollpad(int startx, int starty, int width, int height, string title, COLOR color, BORDER border) : Window(startx, starty, width, height, title, color, border), itsBeginning(0), itsRealHeight(1), itsXPos(0) { delwin(itsWindow); itsWindow = newpad(0,0); }
virtual ~Scrollpad() {}
virtual void Add(string);
virtual void Display();
virtual void Refresh();
virtual void Go(WHERE);
virtual void MoveTo(int newx, int newy) { reallocate_win(newx, newy); }
virtual void Resize(int, int);
virtual void SetBorder(BORDER);
virtual void SetTitle(string);
virtual void Clear();
Scrollpad EmptyClone();
Scrollpad & operator=(const Scrollpad &);
protected:
void print_content();
virtual void recreate_win();
string itsContent;
string itsRawContent;
int itsBeginning;
int itsRealHeight;
int itsXPos;
};
#endif

190
src/settings.cpp Normal file
View File

@@ -0,0 +1,190 @@
/***************************************************************************
* 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 "settings.h"
const string config_file = home_folder + "/.ncmpcpprc";
using std::ifstream;
void DefaultConfiguration(ncmpcpp_config &conf)
{
conf.mpd_music_dir = "/var/lib/mpd/music";
conf.song_list_format = "[green](%l)[/green] {%a - }{%t}|{[white]%f[/white]}";
conf.song_status_format = conf.song_list_format;
conf.song_window_title_format = "{%a - }{%t}|{%f}";
conf.empty_tags_color = clCyan;
conf.header_color = clDefault;
conf.main_color = clYellow;
conf.progressbar_color = clDefault;
conf.statusbar_color = clDefault;
conf.set_window_title = true;
conf.mpd_connection_timeout = 5;
conf.crossfade_time = 5;
conf.playlist_disable_highlight_delay = 5;
conf.message_delay_time = 4;
}
string GetConfigLineValue(const string &line)
{
int i = 0;
int begin = -1, end = -1;
for (string::const_iterator it = line.begin(); it != line.end(); i++, it++)
{
if (*it == '"')
{
if (begin < 0)
begin = i+1;
else
end = i;
}
}
if (begin >= 0 && end >= 0)
return line.substr(begin, end-begin);
else
return "";
}
string IntoStr(COLOR color)
{
string result = "";
if (color == clBlack)
result = "black";
if (color == clRed)
result = "red";
if (color == clGreen)
result = "green";
if (color == clYellow)
result = "yellow";
if (color == clBlue)
result = "blue";
if (color == clMagenta)
result = "magenta";
if (color == clCyan)
result = "cyan";
if (color == clWhite)
result = "white";
return result;
}
COLOR IntoColor(const string &color)
{
COLOR result = clDefault;
if (color == "black")
result = clBlack;
if (color == "red")
result = clRed;
if (color == "green")
result = clGreen;
if (color == "yellow")
result = clYellow;
if (color == "blue")
result = clBlue;
if (color == "magenta")
result = clMagenta;
if (color == "cyan")
result = clCyan;
if (color == "white")
result = clWhite;
return result;
}
void ReadConfiguration(ncmpcpp_config &conf)
{
ifstream f(config_file.c_str());
string config_line;
string v;
vector<string> config_sets;
if (f.is_open())
{
while (!f.eof())
{
getline(f, config_line);
if (!config_line.empty() && config_line[0] != '#')
config_sets.push_back(config_line);
}
for (vector<string>::const_iterator it = config_sets.begin(); it != config_sets.end(); it++)
{
v = GetConfigLineValue(*it);
if (it->find("mpd_music_dir") != string::npos)
if (!v.empty())
conf.mpd_music_dir = v;
if (it->find("mpd_connection_timeout") != string::npos)
if (StrToInt(v))
conf.mpd_connection_timeout = StrToInt(v);
if (it->find("mpd_crossfade_time") != string::npos)
if (StrToInt(v) > 0)
conf.crossfade_time = StrToInt(v);
if (it->find("playlist_disable_highlight_delay") != string::npos)
if (StrToInt(v) >= 0)
conf.playlist_disable_highlight_delay = StrToInt(v);
if (it->find("message_delay_time") != string::npos)
if (StrToInt(v) > 0)
conf.message_delay_time = StrToInt(v);
if (it->find("song_list_format") != string::npos)
if (!v.empty())
conf.song_list_format = v;
if (it->find("song_status_format") != string::npos)
if (!v.empty())
conf.song_status_format = v;
if (it->find("enable_window_title") != string::npos)
conf.set_window_title = v == "yes";
if (it->find("song_window_title_format") != string::npos)
if (!v.empty())
conf.song_window_title_format = v;
if (it->find("empty_tag_color") != string::npos)
if (!v.empty())
conf.empty_tags_color = IntoColor(v);
if (it->find("header_window_color") != string::npos)
if (!v.empty())
conf.header_color = IntoColor(v);
if (it->find("main_window_color") != string::npos)
if (!v.empty())
conf.main_color = IntoColor(v);
if (it->find("progressbar_color") != string::npos)
if (!v.empty())
conf.progressbar_color = IntoColor(v);
if (it->find("statusbar_color") != string::npos)
if (!v.empty())
conf.statusbar_color = IntoColor(v);
}
}
}

58
src/settings.h Normal file
View File

@@ -0,0 +1,58 @@
/***************************************************************************
* 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_SETTINGS_H
#define HAVE_SETTINGS_H
#include <fstream>
#include "ncmpcpp.h"
const string home_folder = getenv("HOME");
struct ncmpcpp_config
{
string mpd_music_dir;
string song_list_format;
string song_status_format;
string song_window_title_format;
COLOR empty_tags_color;
COLOR header_color;
COLOR main_color;
COLOR progressbar_color;
COLOR statusbar_color;
bool set_window_title;
int mpd_connection_timeout;
int crossfade_time;
int playlist_disable_highlight_delay;
int message_delay_time;
};
void DefaultConfiguration(ncmpcpp_config &);
string GetLineValue(const string &);
string IntoStr(COLOR);
COLOR IntoColor(const string &);
void ReadConfiguration(ncmpcpp_config &);
#endif

165
src/song.cpp Normal file
View File

@@ -0,0 +1,165 @@
/***************************************************************************
* 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 "song.h"
extern ncmpcpp_config Config;
string EMPTY;
string UNKNOWN_ARTIST;
string UNKNOWN_TITLE;
string UNKNOWN_ALBUM;
void DefineEmptyTags()
{
const string et_col = IntoStr(Config.empty_tags_color);
EMPTY = "[" + et_col + "]<empty>[/" + et_col + "]";
UNKNOWN_ARTIST = "[" + et_col + "]<no artist>[/" + et_col + "]";
UNKNOWN_TITLE = "[" + et_col + "]<no title>[/" + et_col + "]";
UNKNOWN_ALBUM = "[" + et_col + "]<no album>[/" + et_col + "]";
}
Song::Song(mpd_Song *s) : itsMinutesLength(s->time/60),
itsSecondsLength((s->time-itsMinutesLength*60)),
itsPosition(s->pos),
itsID(s->id),
itsGetEmptyFields(0)
{
s->file ? itsFile = s->file : itsFile = "";
s->artist ? itsArtist = s->artist : itsArtist = "";
s->title ? itsTitle = s->title : itsTitle = "";
s->album ? itsAlbum = s->album : itsAlbum = "";
s->track ? itsTrack = IntoStr(atoi(s->track)) : itsTrack = "";
//s->name ? itsName = s->name : itsName = "";
s->date ? itsYear = s->date : itsYear = "";
s->genre ? itsGenre = s->genre : itsGenre = "";
//s->composer ? itsComposer = s->composer : itsComposer = "";
//s->performer ? itsPerformer = s->performer : itsPerformer = "";
//s->disc ? itsDisc = s->disc : itsDisc = "";
s->comment ? itsComment = s->comment : itsComment = "";
int i = itsFile.size();
try
{
while (itsFile[--i] != '/');
itsDirectory = itsFile.substr(0, i);
itsShortName = itsFile.substr(i+1, itsFile.size()-i-1);
}
catch (std::out_of_range)
{
itsDirectory = "/";
itsShortName = itsFile;
}
}
string Song::GetLength() const
{
std::stringstream ss;
ss << itsMinutesLength << ":";
if (!itsSecondsLength)
{
ss << "00";
return ss.str();
}
if (itsSecondsLength < 10)
ss << "0" << itsSecondsLength;
else
ss << itsSecondsLength;
return ss.str();
}
void Song::Clear()
{
itsFile.clear();
itsShortName.clear();
itsDirectory.clear();
itsArtist.clear();
itsTitle.clear();
itsAlbum.clear();
itsTrack.clear();
//itsName.clear();
itsYear.clear();
itsGenre.clear();
//itsComposer.clear();
//itsPerformer.clear();
//itsDisc.clear();
itsComment.clear();
itsMinutesLength = 0;;
itsSecondsLength = 0;;
itsPosition = 0;;
itsID = 0;
}
bool Song::Empty() const
{
return itsFile.empty() && itsShortName.empty() && itsArtist.empty() && itsTitle.empty() && itsAlbum.empty() && itsTrack.empty() && itsYear.empty() && itsGenre.empty();
}
string Song::GetFile() const
{
return itsGetEmptyFields ? (itsFile.empty() ? "" : itsFile) : (itsFile.empty() ? EMPTY : itsFile);
}
string Song::GetShortFilename() const
{
return itsGetEmptyFields ? (itsShortName.empty() ? "" : itsShortName) : (itsShortName.empty() ? EMPTY : itsShortName);
}
string Song::GetDirectory() const
{
return itsGetEmptyFields ? (itsDirectory.empty() ? "" : itsDirectory) : (itsDirectory.empty() ? EMPTY : itsDirectory);
}
string Song::GetArtist() const
{
return itsGetEmptyFields ? (itsArtist.empty() ? "" : itsArtist) : (itsArtist.empty() ? UNKNOWN_ARTIST : itsArtist);
}
string Song::GetTitle() const
{
return itsGetEmptyFields ? (itsTitle.empty() ? "" : itsTitle) : (itsTitle.empty() ? UNKNOWN_TITLE : itsTitle);
}
string Song::GetAlbum() const
{
return itsGetEmptyFields ? (itsAlbum.empty() ? "" : itsAlbum) : (itsAlbum.empty() ? UNKNOWN_ALBUM : itsAlbum);
}
string Song::GetTrack() const
{
return itsGetEmptyFields ? (itsTrack.empty() ? "" : itsTrack) : (itsTrack.empty() ? EMPTY : itsTrack);
}
string Song::GetYear() const
{
return itsGetEmptyFields ? (itsYear.empty() ? "" : itsYear) : (itsYear.empty() ? EMPTY : itsYear);
}
string Song::GetGenre() const
{
return itsGetEmptyFields ? (itsGenre.empty() ? "" : itsGenre) : (itsGenre.empty() ? EMPTY : itsGenre);
}
string Song::GetComment() const
{
return itsGetEmptyFields ? (itsComment.empty() ? "" : itsComment) : (itsComment.empty() ? EMPTY : itsComment);
}

104
src/song.h Normal file
View File

@@ -0,0 +1,104 @@
/***************************************************************************
* 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_SONG_H
#define HAVE_SONG_H
#include <libmpd/libmpd.h>
#include <cstdlib>
#include <string>
#include <sstream>
#include <stdexcept>
#include "misc.h"
#include "settings.h"
using std::string;
void DefineEmptyTags();
class Song
{
public:
Song() : itsMinutesLength(0), itsSecondsLength(0), itsPosition(0), itsID(0), itsGetEmptyFields(0) { }
Song(mpd_Song *);
~Song() {};
string GetFile() const;
string GetShortFilename() const;
string GetDirectory() const;
string GetArtist() const;
string GetTitle() const;
string GetAlbum() const;
string GetTrack() const;
string GetYear() const;
string GetGenre() const;
//string GetName() const { return itsName; }
//string GetComposer() const { return itsComposer; }
//string GetPerformer() const { return itsPerformer; }
//string GetDisc() const { return itsDisc; }
string GetComment() const;
string GetLength() const;
int GetTotalLength() const { return itsMinutesLength*60+itsSecondsLength; }
int GetMinutesLength() const { return itsMinutesLength; }
int GetSecondsLength() const { return itsSecondsLength; }
int GetPosition() const { return itsPosition; }
int GetID() const { return itsID; }
void SetFile(string str) { itsFile = str; }
void SetShortFilename(string str) { itsShortName = str; }
void SetArtist(string str) { itsArtist = str; }
void SetTitle(string str) { itsTitle = str; }
void SetAlbum(string str) { itsAlbum = str; }
void SetTrack(string str) { itsTrack = str; }
void SetDate(string str) { itsYear = str; }
void SetGenre(string str) { itsGenre = str; }
void SetComment(string str) { itsComment = str; }
void SetPosition(int pos) { itsPosition = pos; }
void GetEmptyFields(bool get) { itsGetEmptyFields = get; }
void Clear();
bool Empty() const;
private:
string itsFile;
string itsShortName;
string itsDirectory;
string itsArtist;
string itsTitle;
string itsAlbum;
string itsTrack;
//string itsName;
string itsYear;
string itsGenre;
//string itsComposer;
//string itsPerformer;
//string itsDisc;
string itsComment;
int itsMinutesLength;
int itsSecondsLength;
int itsPosition;
int itsID;
bool itsGetEmptyFields;
};
//void GetCurrentPlaylist(vector<Song> &);
#endif

410
src/status_checker.cpp Normal file
View File

@@ -0,0 +1,410 @@
/***************************************************************************
* 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 "status_checker.h"
#include "helpers.h"
#include "settings.h"
#define FOR_EACH_MPD_DATA(x) for (; (x); (x) = mpd_data_get_next(x))
extern MpdObj *conn;
extern MpdData *playlist;
extern ncmpcpp_config Config;
extern Menu *mPlaylist;
extern Menu *mBrowser;
extern Menu *mCurrent;
extern Menu *mSearcher;
extern Window *wHeader;
extern Window *wFooter;
extern vector<Song> vPlaylist;
extern vector<Song> vSearched;
extern vector<MpdDataType> vFileType;
extern vector<string> vNameList;
extern time_t block_delay;
extern time_t timer;
extern time_t now;
extern int now_playing;
extern int playing_song_scroll_begin;
extern int block_statusbar_update_delay;
extern long long current_playlist_id;
extern string browsed_dir;
extern string player_state;
extern string volume_state;
extern string switch_state;
extern string mpd_repeat;
extern string mpd_random;
extern string mpd_crossfade;
extern string mpd_db_updating;
extern CurrScreen current_screen;
extern bool header_update_status;
extern bool allow_statusbar_unblock;
extern bool block_progressbar_update;
extern bool block_statusbar_update;
extern bool block_playlist_update;
void TraceMpdStatus()
{
mpd_status_update(conn);
now = time(NULL);
if (now == timer+Config.playlist_disable_highlight_delay && current_screen == csPlaylist)
{
mPlaylist->Highlighting(!Config.playlist_disable_highlight_delay);
mPlaylist->Refresh();
}
if (block_statusbar_update_delay > 0)
{
if (now >= block_delay+block_statusbar_update_delay)
block_statusbar_update_delay = 0;
}
if (!block_statusbar_update_delay)
{
block_statusbar_update_delay = -1;
block_statusbar_update = !allow_statusbar_unblock;
switch (mpd_player_get_state(conn))
{
case MPD_PLAYER_STOP:
NcmpcppStatusChanged(conn, MPD_CST_STATE);
break;
case MPD_PLAYER_PLAY: case MPD_PLAYER_PAUSE:
NcmpcppStatusChanged(conn, MPD_CST_ELAPSED_TIME); // restore status
break;
}
}
//wHeader->WriteXY(0,1, IntoStr(now_playing), 1);
}
void NcmpcppErrorCallback(MpdObj *conn, int errorid, char *msg, void *userdata)
{
ShowMessage(msg);
}
void NcmpcppStatusChanged(MpdObj *conn, ChangedStatusType what)
{
int sx, sy;
wFooter->DisableBB();
wFooter->Bold(1);
wFooter->GetXY(sx, sy);
if (what & MPD_CST_PLAYLIST)
{
if (!block_playlist_update)
{
int playlist_length = mpd_playlist_get_playlist_length(conn);
if (playlist_length != vPlaylist.size())
{
if (playlist_length < vPlaylist.size())
{
mPlaylist->Clear(!playlist_length);
vPlaylist.clear();
}
playlist = mpd_playlist_get_changes(conn, -1);
vPlaylist.reserve(playlist_length);
FOR_EACH_MPD_DATA(playlist)
{
if ((playlist_length > vPlaylist.size() && playlist->song->pos >= vPlaylist.size()) || playlist_length < vPlaylist.size())
{
vPlaylist.push_back(playlist->song);
Song &s = vPlaylist.back();
if (mpd_player_get_current_song_pos(conn) != s.GetPosition())
mPlaylist->AddOption(DisplaySong(s));
else
{
now_playing = mpd_player_get_current_song_pos(conn);
mPlaylist->AddBoldOption(DisplaySong(s));
}
}
}
mpd_data_free(playlist);
current_playlist_id = mpd_playlist_get_playlist_id(conn);
if (current_screen == csPlaylist)
{
if (!playlist_length || mPlaylist->MaxChoice() < mPlaylist->GetHeight())
mPlaylist->Hide();
mPlaylist->Refresh();
}
}
else
{
int i = 1;
mPlaylist->BoldOption(now_playing+1, 0);
now_playing = mpd_player_get_current_song_pos(conn);
mPlaylist->BoldOption(now_playing+1, 1);
playlist = mpd_playlist_get_changes(conn, -1);
for (vector<Song>::iterator it = vPlaylist.begin(); it != vPlaylist.end(); it++, i++)
{
Song ss = playlist->song;
ss.GetEmptyFields(1);
if (it->GetFile() != ss.GetFile() || it->GetTitle() != ss.GetTitle() || it->GetArtist() != ss.GetArtist() || it->GetAlbum() != ss.GetAlbum() || it->GetYear() != ss.GetYear() || it->GetTrack() != ss.GetTrack() || it->GetGenre() != ss.GetGenre() || it->GetComment() != ss.GetComment() || it->GetID() != ss.GetID() || it->GetPosition() != ss.GetPosition())
{
ss.GetEmptyFields(0);
*it = ss;
mPlaylist->UpdateOption(i, DisplaySong(ss));
}
playlist = mpd_data_get_next(playlist);
}
mpd_data_free(playlist);
if (current_screen == csPlaylist)
mPlaylist->Refresh();
}
}
if (vPlaylist.empty())
ShowMessage("Cleared playlist!");
if (!vNameList.empty())
{
bool bold = 0;
for (int i = 0; i < vFileType.size(); i++)
{
if (vFileType[i] == MPD_DATA_TYPE_SONG)
{
for (vector<Song>::const_iterator it = vPlaylist.begin(); it != vPlaylist.end(); it++)
if (it->GetFile() == vNameList[i])
bold = 1;
mBrowser->BoldOption(i+1, bold);
bold = 0;
}
}
if (current_screen == csBrowser)
mBrowser->Refresh();
}
if (!vSearched.empty())
{
bool bold = 0;
int i = search_engine_static_option;
for (vector<Song>::const_iterator it = vSearched.begin(); it != vSearched.end(); it++, i++)
{
for (vector<Song>::const_iterator j = vPlaylist.begin(); j != vPlaylist.end(); j++)
if (j->GetFile() == it->GetFile())
bold = 1;
mSearcher->BoldOption(i+1, bold);
bold = 0;
}
if (current_screen == csSearcher)
mSearcher->Refresh();
}
}
if(what & MPD_CST_DATABASE)
{
GetDirectory(browsed_dir);
mCurrent->Refresh();
}
if ((what & MPD_CST_ELAPSED_TIME))
{
mpd_Song *song = mpd_playlist_get_current_song(conn);
if (song)
{
Song s = song;
WindowTitle(DisplaySong(s, Config.song_window_title_format));
int elapsed = mpd_status_get_elapsed_song_time(conn);
if (!block_statusbar_update)
{
string tracklength = " [" + ShowTime(elapsed) + "/" + s.GetLength() + "]";
ncmpcpp_string_t playing_song = NCMPCPP_TO_WSTRING(OmitBBCodes(DisplaySong(s, Config.song_status_format)));
int max_length_without_scroll = wFooter->GetWidth()-9-tracklength.length();
wFooter->WriteXY(0, 1, player_state);
wFooter->Bold(0);
if (playing_song.length() > max_length_without_scroll)
{
# ifdef UTF8_ENABLED
playing_song += L" ** ";
# else
playing_song += " ** ";
# endif
const int scrollsize = max_length_without_scroll+4;
ncmpcpp_string_t part = playing_song.substr(playing_song_scroll_begin++, scrollsize);
if (part.length() < scrollsize)
part += playing_song.substr(0, scrollsize-part.length());
wFooter->WriteXY(9, 1, part);
if (playing_song_scroll_begin >= playing_song.length())
playing_song_scroll_begin = 0;
}
else
wFooter->WriteXY(9, 1, OmitBBCodes(DisplaySong(s, Config.song_status_format)), 1);
wFooter->Bold(1);
wFooter->WriteXY(wFooter->GetWidth()-tracklength.length(), 1, tracklength);
}
if (!block_progressbar_update)
{
double progressbar_size = (double)elapsed/(s.GetMinutesLength()*60+s.GetSecondsLength());
int howlong = wFooter->GetWidth()*progressbar_size;
wFooter->SetColor(Config.progressbar_color);
mvwhline(wFooter->RawWin(), 0, 0, 0, wFooter->GetWidth());
mvwhline(wFooter->RawWin(), 0, 0, '=',howlong);
mvwaddch(wFooter->RawWin(), 0, howlong, '>');
wFooter->SetColor(Config.statusbar_color);
}
}
}
if (what & MPD_CST_STATE)
{
string state;
int mpd_state = mpd_player_get_state(conn);
switch (mpd_state)
{
case MPD_PLAYER_PLAY:
{
Song &s = vPlaylist[mpd_player_get_current_song_pos(conn)];
now_playing = s.GetPosition();
player_state = "Playing: ";
mPlaylist->BoldOption(now_playing+1, 1);
if (current_screen == csPlaylist)
mPlaylist->Refresh();
break;
}
case MPD_PLAYER_PAUSE:
{
player_state = "[Paused] ";
break;
}
case MPD_PLAYER_STOP:
{
WindowTitle("ncmpc++ ver. 0.1");
wFooter->SetColor(Config.progressbar_color);
mvwhline(wFooter->RawWin(), 0, 0, 0, wFooter->GetWidth());
wFooter->SetColor(Config.statusbar_color);
now_playing = -1;
player_state.clear();
for (int i = 1; i <= mPlaylist->MaxChoice(); i++)
mPlaylist->BoldOption(i, 0);
if (current_screen == csPlaylist)
mPlaylist->Refresh();
break;
}
}
if (!block_statusbar_update || mpd_state == MPD_PLAYER_STOP)
{
if (!player_state.empty())
wFooter->WriteXY(0, 1, player_state);
else
wFooter->WriteXY(0, 1, "", 1);
}
}
if (what & MPD_CST_REPEAT)
{
mpd_repeat = (mpd_player_get_repeat(conn) ? "r" : "");
ShowMessage("Repeat is " + (string)(mpd_repeat.empty() ? "off" : "on"));
header_update_status = 1;
}
if (what & MPD_CST_RANDOM)
{
mpd_random = mpd_player_get_random(conn) ? "z" : "";
ShowMessage("Random is " + (string)(mpd_random.empty() ? "off" : "on"));
header_update_status = 1;
}
if (what & MPD_CST_CROSSFADE)
{
int crossfade = mpd_status_get_crossfade(conn);
mpd_crossfade = crossfade ? "x" : "";
ShowMessage("Crossfade set to " + IntoStr(crossfade) + " seconds");
header_update_status = 1;
}
if (what & MPD_CST_UPDATING)
{
mpd_db_updating = mpd_status_db_is_updating(conn) ? "U" : "";
ShowMessage(mpd_db_updating.empty() ? "Database update finished!" : "Database update started!");
header_update_status = 1;
}
if (header_update_status)
{
switch_state = mpd_repeat + mpd_random + mpd_crossfade + mpd_db_updating;
wHeader->DisableBB();
wHeader->Bold(1);
mvwhline(wHeader->RawWin(), 1, 0, 0, wHeader->GetWidth());
if (!switch_state.empty())
wHeader->WriteXY(wHeader->GetWidth()-switch_state.length()-3, 1, "[" + switch_state + "]");
wHeader->Refresh();
wHeader->Bold(0);
wHeader->EnableBB();
header_update_status = 0;
}
if (what & MPD_CST_SONGID)
{
int id = mpd_player_get_current_song_pos(conn);
if (!vPlaylist.empty() && id >= 0)
{
Song &s = vPlaylist[id];
/*if (s.GetArtist() != UNKNOWN_ARTIST || s.GetTitle() != UNKNOWN_TITLE)
printf("\033]0;%s - %s\7",OmitBBCodes(s.GetArtist()).c_str(), OmitBBCodes(s.GetTitle()).c_str());
else
printf("\033]0;%s\7",s.GetShortFilename().c_str());*/
//wHeader->WriteXY(0, 0, "Song: " + (string)song->artist + " - " + (string)song->title);
if (!mPlaylist->Empty())
{
if (now_playing >= 0)
mPlaylist->BoldOption(now_playing+1, 0);
mPlaylist->BoldOption(s.GetPosition()+1, 1);
now_playing = s.GetPosition();
if (current_screen == csPlaylist)
mPlaylist->Display();
}
if (!mpd_status_get_elapsed_song_time(conn))
{
mvwhline(wFooter->RawWin(), 0, 0, 0, wFooter->GetWidth());
wFooter->Refresh();
}
}
playing_song_scroll_begin = 0;
}
if (what & MPD_CST_VOLUME)
{
int vol = mpd_status_get_volume(conn);
volume_state = " Volume: " + IntoStr(vol) + "%";
wHeader->WriteXY(wHeader->GetWidth()-volume_state.length(), 0, volume_state);
}
wFooter->Bold(0);
wFooter->GotoXY(sx, sy);
wFooter->Refresh();
wFooter->EnableBB();
}

31
src/status_checker.h Normal file
View File

@@ -0,0 +1,31 @@
/***************************************************************************
* 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_STATUS_CHECKER_H
#define HAVE_STATUS_CHECKER_H
#include "ncmpcpp.h"
void TraceMpdStatus();
void NcmpcppStatusChanged(MpdObj *, ChangedStatusType);
void NcmpcppErrorCallback(MpdObj *, int, char *, void *);
#endif

646
src/window.cpp Normal file
View File

@@ -0,0 +1,646 @@
/***************************************************************************
* 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 "window.h"
Window::Window(int startx, int starty, int width, int height, string title, COLOR color, BORDER border) : itsWindow(0), itsWinBorder(0), itsStartX(startx), itsStartY(starty), itsWidth(width), itsHeight(height), BBEnabled(1), itsTitle(title), itsColor(color), itsBaseColor(color), itsBgColor(clDefault), itsBaseBgColor(clDefault), itsBorder(border)
{
if (itsStartX < 0) itsStartX = 0;
if (itsStartY < 0) itsStartY = 0;
if (itsBorder != brNone)
{
itsWinBorder = newpad(itsHeight, itsWidth);
wattron(itsWinBorder,COLOR_PAIR(itsBorder));
box(itsWinBorder,0,0);
itsStartX++;
itsStartY++;
itsWidth -= 2;
itsHeight -= 2;
}
if (!itsTitle.empty())
{
itsStartY += 2;
itsHeight -= 2;
}
if (itsWidth > 0 && itsHeight > 0)
itsWindow = newwin(itsHeight, itsWidth, itsStartY, itsStartX);
else
itsWindow = newwin(0, 0, 0, 0);
SetColor(itsColor);
}
Window::~Window()
{
delwin(itsWindow);
delwin(itsWinBorder);
}
void Window::SetColor(COLOR col, COLOR background)
{
if (col != clDefault)
wattron(itsWindow,COLOR_PAIR(background*8+col));
else
wattroff(itsWindow,COLOR_PAIR(itsColor));
itsColor = col;
itsBgColor = background;
}
void Window::SetBaseColor(COLOR col, COLOR background)
{
itsBaseColor = col;
itsBaseBgColor = background;
}
bool Window::have_to_recreate(BORDER border)
{
if (border == brNone && itsBorder != brNone)
{
delwin(itsWinBorder);
itsStartX--;
itsStartY--;
itsHeight += 2;
itsWidth += 2;
return true;
}
if (border != brNone && itsBorder == brNone)
{
itsWinBorder = newpad(itsHeight,itsWidth);
wattron(itsWinBorder,COLOR_PAIR(border));
box(itsWinBorder,0,0);
itsStartX++;
itsStartY++;
itsHeight -= 2;
itsWidth -= 2;
return true;
}
return false;
}
bool Window::have_to_recreate(string newtitle)
{
if (!newtitle.empty() && itsTitle.empty())
{
itsStartY += 2;
itsHeight -= 2;
return true;
}
if (newtitle.empty() && !itsTitle.empty())
{
itsStartY -= 2;
itsHeight += 2;
return true;
}
return false;
}
void Window::SetBorder(BORDER border)
{
if (have_to_recreate(border))
recreate_win();
itsBorder = border;
}
void Window::SetTitle(string newtitle)
{
if (itsTitle == newtitle)
return;
if (have_to_recreate(newtitle))
recreate_win();
itsTitle = newtitle;
}
void Window::recreate_win()
{
delwin(itsWindow);
itsWindow = newwin(itsHeight, itsWidth, itsStartY, itsStartX);
SetColor(itsColor);
}
bool Window::reallocate_win(int newx, int newy)
{
if (newx < 0 || newy < 0 || (newx == itsStartX && newy == itsStartY)) return false;
itsStartX = newx;
itsStartY = newy;
if (itsBorder != brNone)
{
itsStartX++;
itsStartY++;
}
if (!itsTitle.empty())
itsStartY += 2;
return true;
}
void Window::MoveTo(int newx, int newy)
{
if (reallocate_win(newx, newy))
mvwin(itsWindow, itsStartY, itsStartX);
}
void Window::Resize(int width, int height)
{
if (itsBorder != brNone)
{
delwin(itsWinBorder);
itsWinBorder = newpad(height, width);
wattron(itsWinBorder,COLOR_PAIR(itsBorder));
box(itsWinBorder,0,0);
width -= 2;
height -= 2;
}
if (!itsTitle.empty())
width -= 2;
if (height > 0 && width > 0 && wresize(itsWindow, height, width) == OK)
{
itsHeight = height;
itsWidth = width;
}
}
void Window::show_border() const
{
if (itsBorder != brNone)
{
refresh();
prefresh(itsWinBorder,0,0,GetStartY(),GetStartX(),itsStartY+itsHeight,itsStartX+itsWidth);
}
if (!itsTitle.empty())
{
if (itsBorder != brNone)
{
attron(COLOR_PAIR(itsBorder));
mvhline(itsStartY-1, itsStartX, 0, itsWidth);
}
else
attron(COLOR_PAIR(itsBaseColor));
attron(A_BOLD);
mvaddstr(itsStartY-2, itsStartX, itsTitle.c_str());
attroff(COLOR_PAIR(itsBorder) | A_BOLD);
}
refresh();
}
void Window::Display()
{
show_border();
wrefresh(itsWindow);
}
void Window::Refresh()
{
wrefresh(itsWindow);
}
void Window::Clear()
{
for (int i = 0; i < GetHeight(); i++)
mvwhline(itsWindow, i, 0, 32, GetWidth());
wrefresh(itsWindow);
}
void Window::Hide(char x) const
{
for (int i = GetStartY(); i <= GetHeight()+1; i++)
mvhline(i, GetStartX(), x, GetWidth());
refresh();
}
void Window::Bold(bool bold) const
{
bold ? wattron(itsWindow, A_BOLD) : wattroff(itsWindow, A_BOLD);
}
void Window::Reverse(bool reverse) const
{
reverse ? wattron(itsWindow, A_REVERSE) : wattroff(itsWindow, A_REVERSE);
}
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::Timeout(int timeout) const
{
wtimeout(itsWindow, timeout);
}
void Window::ReadKey(int &input) const
{
keypad(itsWindow, TRUE); input = wgetch(itsWindow); keypad(itsWindow, FALSE);
}
void Window::ReadKey() const
{
wgetch(itsWindow);
}
void Window::Write(const string &str, CLEAR_TO_EOL clrtoeol)
{
if (BBEnabled)
{
bool collect = false;
string color, tmp;
for (string::const_iterator it = str.begin(); it != str.end(); it++)
{
if (*it != '[' && !collect)
tmp += *it;
else
collect = 1;
if (collect)
{
if (*it != '[')
color += *it;
else
{
tmp += color;
color = *it;
}
}
if (*it == ']' || it+1 == str.end())
collect = 0;
if (!collect)
{
waddstr(itsWindow,tmp.c_str());
tmp.clear();
if (is_valid_color(color))
{
const COLOR *colors = into_color(color);
SetColor(colors[0],colors[1]);
delete [] colors;
}
else
tmp += color;
color.clear();
}
}
if (!tmp.empty()) waddstr(itsWindow,tmp.c_str());
}
else
waddstr(itsWindow,str.c_str());
if (clrtoeol) wclrtoeol(itsWindow);
wrefresh(itsWindow);
}
#ifdef UTF8_ENABLED
void Window::Write(const wstring &str, CLEAR_TO_EOL clrtoeol)
{
if (BBEnabled)
{
bool collect = false;
wstring color, tmp;
for (wstring::const_iterator it = str.begin(); it != str.end(); it++)
{
if (*it != '[' && !collect)
tmp += *it;
else
collect = 1;
if (collect)
{
if (*it != '[')
color += *it;
else
{
tmp += color;
color = *it;
}
}
if (*it == ']' || it+1 == str.end())
collect = 0;
if (!collect)
{
waddwstr(itsWindow,tmp.c_str());
tmp.clear();
if (is_valid_color(ToString(color.c_str())))
{
const COLOR *colors = into_color(ToString(color.c_str()));
SetColor(colors[0],colors[1]);
delete [] colors;
}
else
tmp += color;
color.clear();
}
}
if (!tmp.empty()) waddwstr(itsWindow,tmp.c_str());
}
else
waddwstr(itsWindow,str.c_str());
if (clrtoeol) wclrtoeol(itsWindow);
wrefresh(itsWindow);
}
void Window::WriteXY(int x, int y, const wstring &str, CLEAR_TO_EOL cleartoeol)
{
wmove(itsWindow,y,x);
Write(str, cleartoeol);
}
#endif
void Window::WriteXY(int x, int y, const string &str, CLEAR_TO_EOL cleartoeol)
{
wmove(itsWindow,y,x);
Write(str, cleartoeol);
}
string Window::GetString(const string &base, unsigned int length, void (*given_function)()) const
{
curs_set(1);
keypad(itsWindow,TRUE);
int input, minx, x, y, maxx;
wstring tmp;
getyx(itsWindow,y,x);
minx = maxx = x;
tmp = ToWString(base);
wmove(itsWindow,y,minx);
wprintw(itsWindow, "%ls",tmp.c_str());
maxx += tmp.length();
wrefresh(itsWindow);
string tmp_in;
wchar_t wc_in;
x = maxx;
do
{
if (given_function)
given_function();
wmove(itsWindow,y,x);
input = wgetch(itsWindow);
switch (input)
{
case ERR:
continue;
case KEY_UP:
case KEY_DOWN: break;
case KEY_RIGHT:
{
if (x < maxx)
x++;
break;
}
case KEY_BACKSPACE:
{
if (x <= minx) break;
}
case KEY_LEFT:
{
if (x > minx)
x--;
if (input != KEY_BACKSPACE) break; // backspace = left & delete.
}
case KEY_DC:
{
if ((maxx-x) < 1) break;
tmp.erase(tmp.end()-(maxx-x));
wmove(itsWindow,y,x); // for backspace
wdelch(itsWindow);
maxx--;
break;
}
case KEY_HOME:
{
x = minx;
break;
}
case KEY_END:
{
x = maxx;
break;
}
case 10: break;
default:
{
if (maxx-minx >= length)
break;
tmp_in += input;
if (mbtowc(&wc_in, tmp_in.c_str(), MB_CUR_MAX) < 0)
break;
if (maxx == x)
tmp.push_back(wc_in);
else
tmp.insert(tmp.end()-(maxx-x),wc_in);
winsstr(itsWindow, tmp_in.c_str());
tmp_in.clear();
x++;
maxx++;
}
}
}
while (input != 10);
keypad(itsWindow, FALSE);
curs_set(0);
return ToString(tmp);
}
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
{
if (itsBorder != brNone)
return itsWidth+2;
else
return itsWidth;
}
int Window::GetHeight() const
{
int height = itsHeight;
if (itsBorder != brNone)
height += 2;
if (!itsTitle.empty())
height += 2;
return height;
}
int Window::GetStartX() const
{
if (itsBorder != brNone)
return itsStartX-1;
else
return itsStartX;
}
int Window::GetStartY() const
{
int starty = itsStartY;
if (itsBorder != brNone)
starty--;
if (!itsTitle.empty())
starty -= 2;
return starty;
}
string Window::GetTitle() const
{
return itsTitle;
}
COLOR Window::GetColor() const
{
return itsColor;
}
BORDER Window::GetBorder() const
{
return itsBorder;
}
void EnableColors()
{
if (has_colors())
{
start_color();
int num = 1;
if (use_default_colors() != ERR)
for (int i = -1; i < 8; i++)
for (int j = 0; j < 8; j++)
init_pair(num++, j, i);
else
for (int i = 1; i <= 8; i++)
init_pair(i, i, COLOR_BLACK);
}
}
char * ToString(const wchar_t *ws)
{
string s;
for (int i = 0; i < wcslen(ws); i++)
{
char *c = (char *)calloc(MB_CUR_MAX, sizeof(char));
wctomb(c, ws[i]);
s += c;
delete [] c;
}
return (char *)s.c_str();
}
string OmitBBCodes(const string &str)
{
if (str.empty())
return "";
bool collect = false;
string tmp, color, result;
for (string::const_iterator it = str.begin(); it != str.end(); it++)
{
if (*it != '[' && !collect)
tmp += *it;
else
collect = 1;
if (collect)
{
if (*it != '[')
color += *it;
else
{
tmp += color;
color = *it;
}
}
if (*it == ']' || it+1 == str.end())
collect = 0;
if (!collect)
{
result += tmp;
tmp.clear();
if (!is_valid_color(color))
tmp += color;
color.clear();
}
}
if (!tmp.empty()) result += tmp;
return result;
}
wchar_t * ToWString(const char *s)
{
wchar_t *ws = (wchar_t *)calloc(strlen(s)+1, sizeof(wchar_t));
mbstowcs(ws, s, strlen(s));
return ws;
}
string ToString(const wstring &ws)
{
string s;
for (wstring::const_iterator it = ws.begin(); it != ws.end(); it++)
{
char *c = (char *)calloc(MB_CUR_MAX, sizeof(char));
wctomb(c, *it);
s += c;
delete [] c;
}
return s;
}
wstring ToWString(const string &s)
{
wchar_t *ws = (wchar_t *)calloc(s.length()+1, sizeof(wchar_t));
mbstowcs(ws, s.c_str(), s.length());
wstring result = ws;
delete [] ws;
return result;
}

132
src/window.h Normal file
View File

@@ -0,0 +1,132 @@
/***************************************************************************
* 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_WINDOW_H
#define HAVE_WINDOW_H
#ifdef UTF8_ENABLED
# include <ncursesw/ncurses.h>
#else
# include <ncurses.h>
#endif
#include <vector>
#include <string>
#include <cstdlib>
#include <cstring>
#ifdef UTF8_ENABLED
# define TO_STRING(x) ToString(x)
#else
# define TO_STRING(x) x
#endif
typedef bool CLEAR_TO_EOL;
using std::string;
using std::wstring;
using std::vector;
enum COLOR { clDefault, clBlack, clRed, clGreen, clYellow, clBlue, clMagenta, clCyan, clWhite };
enum BORDER { brNone, brBlack, brRed, brGreen, brYellow, brBlue, brMagenta, brCyan, brWhite };
enum WHERE { UP, DOWN, PAGE_UP, PAGE_DOWN, HOME, END };
void EnableColors();
char * ToString(const wchar_t *);
wchar_t * ToWString(const char *);
string ToString(const wstring &);
wstring ToWString(const string &);
bool is_valid_color(const string &);
string OmitBBCodes(const string &);
class Window
{
public:
Window(int, int, int, int, string, COLOR, BORDER);
virtual ~Window();
virtual WINDOW *RawWin() { return itsWindow; }
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(string);
virtual void MoveTo(int, int);
virtual void Resize(int, int);
virtual void Display();
virtual void Refresh();
virtual void Clear();
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 Timeout(int) const;
virtual void ReadKey(int &) const;
virtual void ReadKey() const;
virtual void Write(const string &, CLEAR_TO_EOL = 1);
virtual void WriteXY(int, int, const string &, CLEAR_TO_EOL = 0);
#ifdef UTF8_ENABLED
virtual void Write(const wstring &, CLEAR_TO_EOL = 1);
virtual void WriteXY(int, int, const wstring &, CLEAR_TO_EOL = 0);
#endif
virtual string GetString(int num, void (*ptr)() = NULL) const { return GetString("", num, ptr); }
virtual string GetString(const string &str, void (*ptr)()) const { return GetString(str, -1, ptr); }
virtual string GetString(const string &, unsigned int = -1, void (*)() = NULL) const;
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;
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
protected:
virtual bool have_to_recreate(string);
virtual bool have_to_recreate(BORDER);
virtual bool reallocate_win(int, int);
virtual void recreate_win();
virtual void show_border() const;
virtual const COLOR * into_color(const string &) const;
//bool is_valid_color(const string &);
WINDOW *itsWindow;
WINDOW *itsWinBorder;
int itsStartX;
int itsStartY;
int itsWidth;
int itsHeight;
bool BBEnabled;
string itsTitle;
COLOR itsColor;
COLOR itsBaseColor;
COLOR itsBgColor;
COLOR itsBaseBgColor;
BORDER itsBorder;
};
#endif