add multiple items selection on playlist screen and nested colors support

This commit is contained in:
unK
2008-08-31 04:09:07 +02:00
parent ceff30c9ec
commit f8f414d93a
12 changed files with 535 additions and 320 deletions

View File

@@ -89,6 +89,10 @@
#
#key_lyrics = 'l'
#
#key_reverse_selection = 'v'
#
#key_deselect_all = 'V'
#
#key_clear = 'c'
#
#key_crop = 'C'

View File

@@ -70,6 +70,10 @@
#
#browser_playlist_prefix = "[red]playlist[/red] "
#
#selected_item_prefix = "[magenta]"
#
#selected_item_suffix = "[/magenta]"
#
##### various settings #####
#
#autocenter_mode = "no"

View File

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

View File

@@ -25,6 +25,7 @@ extern MPDConnection *Mpd;
extern ncmpcpp_config Config;
extern Menu *mPlaylist;
extern Menu *mBrowser;
extern Menu *mTagEditor;
extern Menu *mSearcher;
@@ -61,6 +62,40 @@ extern string UNKNOWN_ARTIST;
extern string UNKNOWN_TITLE;
extern string UNKNOWN_ALBUM;
void DeleteSong(int id)
{
Mpd->QueueDeleteSong(id);
delete vPlaylist[id];
vPlaylist.erase(vPlaylist.begin()+id);
mPlaylist->DeleteOption(id+1);
}
bool MoveSongUp(int pos)
{
if (pos > 0 && !mPlaylist->Empty() && current_screen == csPlaylist)
{
std::swap<Song *>(vPlaylist[pos], vPlaylist[pos-1]);
mPlaylist->Swap(pos, pos-1);
Mpd->Move(pos, pos-1);
return true;
}
else
return false;
}
bool MoveSongDown(int pos)
{
if (pos+1 < vPlaylist.size() && !mPlaylist->Empty() && current_screen == csPlaylist)
{
std::swap<Song *>(vPlaylist[pos+1], vPlaylist[pos]);
mPlaylist->Swap(pos+1, pos);
Mpd->Move(pos, pos+1);
return true;
}
else
return false;
}
string DisplayKeys(int *key, int size)
{
bool backspace = 1;
@@ -631,14 +666,14 @@ bool GetSongInfo(Song &s)
mTagEditor->Clear();
mTagEditor->Reset();
mTagEditor->AddStaticOption("[b][white]Song name: [green][/b]" + s.GetShortFilename());
mTagEditor->AddStaticOption("[b][white]Location in DB: [green][/b]" + s.GetDirectory());
mTagEditor->AddStaticOption("[b][white]Song name: [/white][green][/b]" + s.GetShortFilename() + "[/green]");
mTagEditor->AddStaticOption("[b][white]Location in DB: [/white][green][/b]" + s.GetDirectory() + "[/green]");
mTagEditor->AddStaticOption("");
mTagEditor->AddStaticOption("[b][white]Length: [green][/b]" + s.GetLength() + "[/green]");
mTagEditor->AddStaticOption("[b][white]Length: [/white][green][/b]" + s.GetLength() + "[/green]");
# ifdef HAVE_TAGLIB_H
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->AddStaticOption("[b][white]Bitrate: [/white][green][/b]" + IntoStr(f.audioProperties()->bitrate()) + " kbps[/green]");
mTagEditor->AddStaticOption("[b][white]Sample rate: [/white][green][/b]" + IntoStr(f.audioProperties()->sampleRate()) + " Hz[/green]");
mTagEditor->AddStaticOption("[b][white]Channels: [/white][green][/b]" + (string)(f.audioProperties()->channels() == 1 ? "Mono" : "Stereo") + "[/green]");
# endif
mTagEditor->AddSeparator();

View File

@@ -30,6 +30,10 @@
extern ncmpcpp_config Config;
void DeleteSong(int);
bool MoveSongUp(int);
bool MoveSongDown(int);
string DisplayKeys(int *, int = 2);
bool Keypressed(int, const int *);
bool SortSongsByTrack(Song *, Song *);

View File

@@ -70,8 +70,6 @@ void Menu::AddOption(const string &str, LOCATION location, HAVE_SEPARATOR separa
new_option->content = str;
new_option->location = location;
new_option->have_separator = separator;
new_option->is_static = 0;
new_option->is_bold = 0;
itsOptions.push_back(new_option);
if (itsOptions.size() > itsBeginning && itsOptions.size() <= itsBeginning+itsHeight)
@@ -84,7 +82,6 @@ void Menu::AddBoldOption(const string &str, LOCATION location, HAVE_SEPARATOR se
new_option->content = str;
new_option->location = location;
new_option->have_separator = separator;
new_option->is_static = 0;
new_option->is_bold = 1;
itsOptions.push_back(new_option);
@@ -99,7 +96,6 @@ void Menu::AddStaticOption(const string &str, LOCATION location, HAVE_SEPARATOR
new_option->location = location;
new_option->have_separator = separator;
new_option->is_static = 1;
new_option->is_bold = 0;
itsOptions.push_back(new_option);
itsStaticsNumber++;
@@ -199,17 +195,18 @@ string Menu::GetOption(int i) const
void Menu::DeleteOption(int no)
{
no--;
try
{
if (itsOptions.at(no-1)->is_static)
if (itsOptions.at(no)->is_static)
itsStaticsNumber--;
}
catch (std::out_of_range)
{
return;
}
delete itsOptions[no-1];
itsOptions.erase(itsOptions.begin()+no-1);
delete itsOptions[no];
itsOptions.erase(itsOptions.begin()+no);
if (itsHighlight > itsOptions.size()-1)
itsHighlight = itsOptions.size()-1;
@@ -220,14 +217,14 @@ void Menu::DeleteOption(int no)
if (itsBeginning > MaxBeginning)
{
itsBeginning = MaxBeginning;
wmove(itsWindow, no-1-itsBeginning, 0);
wmove(itsWindow, no-itsBeginning, 0);
wdeleteln(itsWindow);
wscrl(itsWindow, -1);
NeedsRedraw.push_back(itsBeginning);
}
else
{
wmove(itsWindow, no-1-itsBeginning, 0);
wmove(itsWindow, no-itsBeginning, 0);
wdeleteln(itsWindow);
}
NeedsRedraw.push_back(itsHighlight);
@@ -236,6 +233,19 @@ void Menu::DeleteOption(int no)
idlok(itsWindow, 0);
}
void Menu::Swap(int one, int two)
{
try
{
std::swap<Option *>(itsOptions.at(one), itsOptions.at(two));
NeedsRedraw.push_back(one);
NeedsRedraw.push_back(two);
}
catch (std::out_of_range)
{
}
}
void Menu::redraw_screen()
{
NeedsRedraw.clear();
@@ -260,7 +270,7 @@ void Menu::Refresh(bool redraw_whole_window)
if (itsBeginning > MaxBeginning)
itsBeginning = MaxBeginning;
if (itsHighlight > itsOptions.size()-1)
if (itsHighlight >= itsOptions.size()-1)
Highlight(itsOptions.size());
if (redraw_whole_window)
@@ -278,6 +288,10 @@ void Menu::Refresh(bool redraw_whole_window)
}
int line = *it-itsBeginning;
if (line < 0 || line+1 > itsHeight) // do not draw if line should be invisible anyway
continue;
COLOR old_basecolor = itsBaseColor;
if (*it == itsHighlight && itsHighlightEnabled)
@@ -322,9 +336,15 @@ void Menu::Refresh(bool redraw_whole_window)
}
# ifdef UTF8_ENABLED
WriteXY(x, line, itsWidth, ToWString(itsOptions[*it]->content), 0);
if (itsOptions[*it]->selected)
WriteXY(x, line, itsWidth, ToWString(itsSelectedPrefix + itsOptions[*it]->content + itsSelectedSuffix), 0);
else
WriteXY(x, line, itsWidth, ToWString(itsOptions[*it]->content), 0);
# else
WriteXY(x, line, itsWidth, itsOptions[*it]->content, 0);
if (itsOptions[*it]->selected)
WriteXY(x, line, itsWidth, itsSelectedPrefix + itsOptions[*it]->content + itsSelectedSuffix, 0);
else
WriteXY(x, line, itsWidth, itsOptions[*it]->content, 0);
# endif
if (!ch && (itsOptions[*it]->location == lCenter || itsOptions[*it]->location == lLeft))
@@ -335,7 +355,6 @@ void Menu::Refresh(bool redraw_whole_window)
AltCharset(0);
}
}
line++;
if (*it == itsHighlight && itsHighlightEnabled)
{
@@ -345,6 +364,9 @@ void Menu::Refresh(bool redraw_whole_window)
}
if (itsOptions[*it]->is_bold)
Bold(0);
while (!itsColors.empty()) // clear color stack as some items are
itsColors.pop(); // too long to close all tags properly
}
NeedsRedraw.clear();
wrefresh(itsWindow);
@@ -539,6 +561,55 @@ void Menu::Clear(bool clear_screen)
Window::Clear();
}
void Menu::Select(int option, bool selected)
{
option--;
try
{
if (itsOptions.at(option)->selected != selected)
NeedsRedraw.push_back(option);
itsOptions.at(option)->selected = selected;
}
catch (std::out_of_range)
{
}
}
bool Menu::Selected(int option)
{
option--;
try
{
return itsOptions.at(option)->selected;
}
catch (std::out_of_range)
{
return false;
}
}
bool Menu::IsAnySelected()
{
bool result = 0;
for (vector<Option *>::const_iterator it = itsOptions.begin(); it != itsOptions.end(); it++)
{
if ((*it)->selected)
{
result = 1;
break;
}
}
return result;
}
void Menu::GetSelectedList(vector<int> &v)
{
int i = 1;
for (vector<Option *>::const_iterator it = itsOptions.begin(); it != itsOptions.end(); it++, i++)
if ((*it)->selected)
v.push_back(i);
}
int Menu::GetRealChoice() const
{
int real_choice = 0;

View File

@@ -33,9 +33,11 @@ enum LOCATION { lLeft, lCenter, lRight };
struct Option
{
Option() : is_static(0), is_bold(0), selected(0), have_separator(0) { }
string content;
bool is_static;
bool is_bold;
bool selected;
bool have_separator;
LOCATION location;
};
@@ -43,7 +45,7 @@ struct Option
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), itsBeginning(0), itsHighlight(0), itsHighlightColor(itsBaseColor), itsHighlightEnabled(1) { SetColor(color); }
Menu(int startx, int starty, int width, int height, string title, COLOR color, BORDER border) : Window(startx, starty, width, height, title, color, border), itsSelectedPrefix("[r]"), itsSelectedSuffix("[/r]"), itsStaticsNumber(0), itsBeginning(0), itsHighlight(0), itsHighlightColor(itsBaseColor), itsHighlightEnabled(1) { SetColor(color); }
virtual ~Menu();
virtual void Add(string str) { AddOption(str); }
@@ -56,6 +58,7 @@ class Menu : public Window
void BoldOption(int, IS_BOLD);
void MakeStatic(int, IS_STATIC);
void DeleteOption(int);
void Swap(int, int);
string GetCurrentOption() const;
string GetOption(int i) const;
@@ -66,6 +69,13 @@ class Menu : public Window
virtual void Reset();
virtual void Clear(bool clear_screen = 1);
void Select(int, bool);
bool Selected(int);
bool IsAnySelected();
void SetSelectPrefix(string str) { itsSelectedPrefix = str; }
void SetSelectSuffix(string str) { itsSelectedSuffix = str; }
void GetSelectedList(vector<int> &);
void HighlightColor(COLOR col) { itsHighlightColor = col; NeedsRedraw.push_back(itsHighlight); }
void Highlighting(bool hl) { itsHighlightEnabled = hl; NeedsRedraw.push_back(itsHighlight); Refresh(); }
@@ -82,6 +92,9 @@ class Menu : public Window
vector<Option *> itsOptions;
vector<int> NeedsRedraw;
string itsSelectedPrefix;
string itsSelectedSuffix;
int itsStaticsNumber;
int count_length(string);

View File

@@ -190,6 +190,9 @@ int main(int argc, char *argv[])
main_height++;
mPlaylist = new Menu(0, main_start_y, COLS, main_height, "", Config.main_color, brNone);
mPlaylist->SetSelectPrefix(Config.selected_item_prefix);
mPlaylist->SetSelectSuffix(Config.selected_item_suffix);
mBrowser = static_cast<Menu *>(mPlaylist->EmptyClone());
mTagEditor = static_cast<Menu *>(mPlaylist->EmptyClone());
mSearcher = static_cast<Menu *>(mPlaylist->EmptyClone());
@@ -253,11 +256,14 @@ int main(int argc, char *argv[])
sHelp->Add(" [b]Keys - Playlist screen\n -----------------------------------------[/b]\n");
sHelp->Add(DisplayKeys(Key.Enter) + "Play\n");
sHelp->Add(DisplayKeys(Key.Delete) + "Delete song from playlist\n");
sHelp->Add(DisplayKeys(Key.Delete) + "Delete item/selected items from playlist\n");
sHelp->Add(DisplayKeys(Key.Space) + "Select/deselect item\n");
sHelp->Add(DisplayKeys(Key.ReverseSelection) + "Reverse selection\n");
sHelp->Add(DisplayKeys(Key.DeselectAll) + "Deselect all items\n");
sHelp->Add(DisplayKeys(Key.Clear) + "Clear whole playlist\n");
sHelp->Add(DisplayKeys(Key.Crop) + "Clear playlist but hold currently playing song\n");
sHelp->Add(DisplayKeys(Key.MvSongUp) + "Move song up\n");
sHelp->Add(DisplayKeys(Key.MvSongDown) + "Move song down\n");
sHelp->Add(DisplayKeys(Key.Crop) + "Clear playlist but hold currently playing/selected items\n");
sHelp->Add(DisplayKeys(Key.MvSongUp) + "Move item up\n");
sHelp->Add(DisplayKeys(Key.MvSongDown) + "Move item down\n");
sHelp->Add(DisplayKeys(Key.Add) + "Add url/file/directory to playlist\n");
sHelp->Add(DisplayKeys(Key.SavePlaylist) + "Save playlist\n");
sHelp->Add(DisplayKeys(Key.GoToNowPlaying) + "Go to currently playing position\n");
@@ -270,8 +276,8 @@ int main(int argc, char *argv[])
sHelp->Add(DisplayKeys(Key.Delete) + "Delete playlist\n\n\n");
sHelp->Add(" [b]Keys - Search engine\n -----------------------------------------[/b]\n");
sHelp->Add(DisplayKeys(Key.Enter) + "Change option/Add to playlist and play song\n");
sHelp->Add(DisplayKeys(Key.Space) + "Add song to playlist\n\n\n");
sHelp->Add(DisplayKeys(Key.Enter) + "Change option/Add to playlist and play\n");
sHelp->Add(DisplayKeys(Key.Space) + "Add item to playlist\n\n\n");
sHelp->Add(" [b]Keys - Media library\n -----------------------------------------[/b]\n");
sHelp->Add(DisplayKeys(&Key.VolumeDown[0], 1) + "Previous column\n");
@@ -841,6 +847,7 @@ int main(int argc, char *argv[])
TagLib::FileRef f(path_to_file.c_str());
if (!f.isNull())
{
ShowMessage("Updating tags...");
s.GetEmptyFields(1);
f.tag()->setTitle(NCMPCPP_TO_WSTRING(s.GetTitle()));
f.tag()->setArtist(NCMPCPP_TO_WSTRING(s.GetArtist()));
@@ -851,6 +858,7 @@ int main(int argc, char *argv[])
f.tag()->setComment(NCMPCPP_TO_WSTRING(s.GetComment()));
s.GetEmptyFields(0);
f.save();
ShowMessage("Tags updated!");
Mpd->UpdateDirectory(s.GetDirectory());
if (prev_screen == csSearcher)
{
@@ -1125,7 +1133,13 @@ int main(int argc, char *argv[])
}
else if (Keypressed(input, Key.Space))
{
if (current_screen == csBrowser)
if (current_screen == csPlaylist)
{
int i = mPlaylist->GetChoice();
mPlaylist->Select(i, !mPlaylist->Selected(i));
mPlaylist->Go(DOWN);
}
else if (current_screen == csBrowser)
{
int ci = mBrowser->GetChoice()-1;
switch (vBrowser[ci].type)
@@ -1241,27 +1255,32 @@ int main(int argc, char *argv[])
{
if (!mPlaylist->Empty() && current_screen == csPlaylist)
{
block_playlist_update = 1;
dont_change_now_playing = 1;
mPlaylist->Timeout(50);
int id = mPlaylist->GetChoice()-1;
while (!vPlaylist.empty() && Keypressed(input, Key.Delete))
if (mPlaylist->IsAnySelected())
{
TraceMpdStatus();
timer = time(NULL);
id = mPlaylist->GetChoice()-1;
Mpd->QueueDeleteSong(id);
delete vPlaylist[id];
vPlaylist.erase(vPlaylist.begin()+id);
mPlaylist->DeleteOption(id+1);
mPlaylist->Refresh();
mPlaylist->ReadKey(input);
vector<int> list;
mPlaylist->GetSelectedList(list);
for (vector<int>::const_reverse_iterator it = list.rbegin(); it != list.rend(); it++)
DeleteSong(*it-1);
ShowMessage("Selected items deleted!");
redraw_me = 1;
}
else
{
block_playlist_update = 1;
dont_change_now_playing = 1;
mPlaylist->Timeout(50);
while (!vPlaylist.empty() && Keypressed(input, Key.Delete))
{
TraceMpdStatus();
timer = time(NULL);
DeleteSong(mPlaylist->GetChoice()-1);
mPlaylist->Refresh();
mPlaylist->ReadKey(input);
}
mPlaylist->Timeout(ncmpcpp_window_timeout);
dont_change_now_playing = 0;
}
Mpd->CommitQueue();
mPlaylist->Timeout(ncmpcpp_window_timeout);
dont_change_now_playing = 0;
}
if (current_screen == csBrowser)
{
@@ -1323,58 +1342,44 @@ int main(int argc, char *argv[])
else if (Keypressed(input, Key.MvSongUp))
{
block_playlist_update = 1;
int pos = mPlaylist->GetChoice()-1;
if (pos > 0 && !mPlaylist->Empty() && current_screen == csPlaylist)
if (mPlaylist->IsAnySelected())
{
std::swap<Song *>(vPlaylist[pos], vPlaylist[pos-1]);
if (pos == now_playing)
vector<int> list;
mPlaylist->GetSelectedList(list);
mPlaylist->Highlight(list[(list.size()-1)/2]-1);
for (vector<int>::const_iterator it = list.begin(); it != list.end(); it++)
{
now_playing--;
mPlaylist->BoldOption(pos, 1);
mPlaylist->BoldOption(pos+1, 0);
}
else
{
if (pos-1 == now_playing)
if (!MoveSongUp(*it-1))
{
now_playing++;
mPlaylist->BoldOption(pos, 0);
mPlaylist->BoldOption(pos+1, 1);
mPlaylist->Go(DOWN);
break;
}
}
mPlaylist->UpdateOption(pos, DisplaySong(*vPlaylist[pos-1]));
mPlaylist->UpdateOption(pos+1, DisplaySong(*vPlaylist[pos]));
Mpd->Move(pos, pos-1);
mPlaylist->Go(UP);
}
else
if (MoveSongUp(mPlaylist->GetChoice()-1))
mPlaylist->Go(UP);
}
else if (Keypressed(input, Key.MvSongDown))
{
block_playlist_update = 1;
int pos = mPlaylist->GetChoice()-1;
if (pos+1 < vPlaylist.size() && !mPlaylist->Empty() && current_screen == csPlaylist)
if (mPlaylist->IsAnySelected())
{
std::swap<Song *>(vPlaylist[pos+1], vPlaylist[pos]);
if (pos == now_playing)
vector<int> list;
mPlaylist->GetSelectedList(list);
mPlaylist->Highlight(list[(list.size()-1)/2]+1);
for (vector<int>::const_reverse_iterator it = list.rbegin(); it != list.rend(); it++)
{
now_playing++;
mPlaylist->BoldOption(pos+1, 0);
mPlaylist->BoldOption(pos+2, 1);
}
else
{
if (pos+1 == now_playing)
if (!MoveSongDown(*it-1))
{
now_playing--;
mPlaylist->BoldOption(pos+1, 1);
mPlaylist->BoldOption(pos+2, 0);
mPlaylist->Go(UP);
break;
}
}
mPlaylist->UpdateOption(pos+2, DisplaySong(*vPlaylist[pos+1]));
mPlaylist->UpdateOption(pos+1, DisplaySong(*vPlaylist[pos]));
Mpd->Move(pos, pos+1);
mPlaylist->Go(DOWN);
}
else
if (MoveSongDown(mPlaylist->GetChoice()-1))
mPlaylist->Go(DOWN);
}
else if (Keypressed(input, Key.Add))
{
@@ -1550,20 +1555,57 @@ int main(int argc, char *argv[])
Mpd->Seek(vPlaylist[now_playing]->GetTotalLength()*newpos/100.0);
UNLOCK_STATUSBAR;
}
else if (Keypressed(input, Key.ReverseSelection))
{
if (current_screen == csPlaylist)
{
for (int i = 1; i <= mPlaylist->MaxChoice(); i++)
mPlaylist->Select(i, !mPlaylist->Selected(i));
ShowMessage("Selection reversed!");
}
}
else if (Keypressed(input, Key.DeselectAll))
{
if (current_screen == csPlaylist && mPlaylist->IsAnySelected())
{
for (int i = 1; i <= mPlaylist->MaxChoice(); i++)
mPlaylist->Select(i, 0);
ShowMessage("Items deselected!");
}
}
else if (Keypressed(input, Key.Crop))
{
if (now_playing < 0)
if (mPlaylist->IsAnySelected())
{
ShowMessage("Nothing is playing now!");
continue;
for (int i = 0; i < mPlaylist->MaxChoice(); i++)
{
if (!mPlaylist->Selected(i+1) && i != now_playing)
Mpd->QueueDeleteSongId(vPlaylist[i]->GetID());
}
// if mpd deletes now playing song deletion will be sluggishly slow
// then so we have to assure it will be deleted at the very end.
if (!mPlaylist->Selected(now_playing+1))
Mpd->QueueDeleteSongId(vPlaylist[now_playing]->GetID());
ShowMessage("Deleting all items but selected...");
Mpd->CommitQueue();
ShowMessage("Items deleted!");
}
else
{
if (now_playing < 0)
{
ShowMessage("Nothing is playing now!");
continue;
}
for (SongList::iterator it = vPlaylist.begin(); it != vPlaylist.begin()+now_playing; it++)
Mpd->QueueDeleteSongId((*it)->GetID());
for (SongList::iterator it = vPlaylist.begin()+now_playing+1; it != vPlaylist.end(); it++)
Mpd->QueueDeleteSongId((*it)->GetID());
ShowMessage("Deleting all items except now playing one...");
Mpd->CommitQueue();
ShowMessage("Items deleted!");
}
for (SongList::iterator it = vPlaylist.begin(); it != vPlaylist.begin()+now_playing; it++)
Mpd->QueueDeleteSongId((*it)->GetID());
for (SongList::iterator it = vPlaylist.begin()+now_playing+1; it != vPlaylist.end(); it++)
Mpd->QueueDeleteSongId((*it)->GetID());
ShowMessage("Deleting all songs except now playing one...");
Mpd->CommitQueue();
ShowMessage("Songs deleted!");
}
else if (Keypressed(input, Key.Clear))
{

View File

@@ -65,6 +65,8 @@ void DefaultKeys(ncmpcpp_keys &keys)
keys.EditTags[0] = 'e';
keys.GoToPosition[0] = 'g';
keys.Lyrics[0] = 'l';
keys.ReverseSelection[0] = 'v';
keys.DeselectAll[0] = 'V';
keys.Clear[0] = 'c';
keys.Crop[0] = 'C';
keys.MvSongUp[0] = 'm';
@@ -114,6 +116,8 @@ void DefaultKeys(ncmpcpp_keys &keys)
keys.EditTags[1] = null_key;
keys.GoToPosition[1] = null_key;
keys.Lyrics[1] = null_key;
keys.ReverseSelection[1] = null_key;
keys.DeselectAll[1] = null_key;
keys.Clear[1] = null_key;
keys.Crop[1] = null_key;
keys.MvSongUp[1] = null_key;
@@ -134,6 +138,8 @@ void DefaultConfiguration(ncmpcpp_config &conf)
conf.song_window_title_format = "{%a - }{%t}|{%f}";
conf.song_library_format = "{%n - }{%t}|{%f}";
conf.browser_playlist_prefix = "[red](playlist)[/red] ";
conf.selected_item_prefix = "[magenta]";
conf.selected_item_suffix = "[/magenta]";
conf.empty_tags_color = clCyan;
conf.header_color = clDefault;
conf.volume_color = clDefault;
@@ -341,6 +347,10 @@ void ReadKeys(ncmpcpp_keys &keys)
GetKeys(*it, keys.GoToPosition);
else if (it->find("key_lyrics ") != string::npos)
GetKeys(*it, keys.Lyrics);
else if (it->find("key_reverse_selection ") != string::npos)
GetKeys(*it, keys.ReverseSelection);
else if (it->find("key_deselect_all ") != string::npos)
GetKeys(*it, keys.DeselectAll);
else if (it->find("key_clear ") != string::npos)
GetKeys(*it, keys.Clear);
else if (it->find("key_crop ") != string::npos)
@@ -386,105 +396,129 @@ void ReadConfiguration(ncmpcpp_config &conf)
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)
}
else 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)
}
else 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)
}
else 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)
}
else 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())
}
else if (it->find("song_list_format") != string::npos)
{
if (!v.empty())
conf.song_list_format = v;
if (it->find("song_status_format") != string::npos)
}
else if (it->find("song_status_format") != string::npos)
{
if (!v.empty())
conf.song_status_format = v;
if (it->find("song_library_format") != string::npos)
}
else if (it->find("song_library_format") != string::npos)
{
if (!v.empty())
conf.song_library_format = v;
if (it->find("browser_playlist_prefix") != string::npos)
}
else if (it->find("browser_playlist_prefix") != string::npos)
{
if (!v.empty())
conf.browser_playlist_prefix = v;
if (it->find("colors_enabled") != string::npos)
}
else if (it->find("selected_item_prefix") != string::npos)
{
if (!v.empty())
conf.selected_item_prefix = v;
}
else if (it->find("selected_item_suffix") != string::npos)
{
if (!v.empty())
conf.selected_item_suffix = v;
}
else if (it->find("colors_enabled") != string::npos)
conf.colors_enabled = v == "yes";
if (it->find("header_visibility") != string::npos)
else if (it->find("header_visibility") != string::npos)
conf.header_visibility = v == "yes";
if (it->find("statusbar_visibility") != string::npos)
else if (it->find("statusbar_visibility") != string::npos)
conf.statusbar_visibility = v == "yes";
if (it->find("autocenter_mode") != string::npos)
else if (it->find("autocenter_mode") != string::npos)
conf.autocenter_mode = v == "yes";
if (it->find("repeat_one_mode") != string::npos)
else if (it->find("repeat_one_mode") != string::npos)
conf.repeat_one_mode = v == "yes";
if (it->find("find_mode") != string::npos)
else if (it->find("find_mode") != string::npos)
conf.wrapped_search = v == "wrapped";
if (it->find("enable_window_title") != string::npos)
else if (it->find("enable_window_title") != string::npos)
conf.set_window_title = v == "yes";
if (it->find("song_window_title_format") != string::npos)
else 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)
}
else 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)
}
else if (it->find("header_window_color") != string::npos)
{
if (!v.empty())
conf.header_color = IntoColor(v);
if (it->find("volume_color") != string::npos)
}
else if (it->find("volume_color") != string::npos)
{
if (!v.empty())
conf.volume_color = IntoColor(v);
if (it->find("state_line_color") != string::npos)
}
else if (it->find("state_line_color") != string::npos)
{
if (!v.empty())
conf.state_line_color = IntoColor(v);
if (it->find("state_flags_color") != string::npos)
}
else if (it->find("state_flags_color") != string::npos)
{
if (!v.empty())
conf.state_flags_color = IntoColor(v);
if (it->find("main_window_color") != string::npos)
}
else if (it->find("main_window_color") != string::npos)
{
if (!v.empty())
conf.main_color = IntoColor(v);
if (it->find("main_window_highlight_color") != string::npos)
}
else if (it->find("main_window_highlight_color") != string::npos)
{
if (!v.empty())
conf.main_highlight_color = IntoColor(v);
if (it->find("progressbar_color") != string::npos)
}
else if (it->find("progressbar_color") != string::npos)
{
if (!v.empty())
conf.progressbar_color = IntoColor(v);
if (it->find("statusbar_color") != string::npos)
}
else if (it->find("statusbar_color") != string::npos)
{
if (!v.empty())
conf.statusbar_color = IntoColor(v);
if (it->find("library_active_column_color") != string::npos)
}
else if (it->find("library_active_column_color") != string::npos)
{
if (!v.empty())
conf.library_active_column_color = IntoColor(v);
}
}
f.close();
}

View File

@@ -67,6 +67,8 @@ struct ncmpcpp_keys
int EditTags[2];
int GoToPosition[2];
int Lyrics[2];
int ReverseSelection[2];
int DeselectAll[2];
int Clear[2];
int Crop[2];
int MvSongUp[2];
@@ -88,6 +90,9 @@ struct ncmpcpp_config
string song_library_format;
string browser_playlist_prefix;
string selected_item_prefix;
string selected_item_suffix;
COLOR empty_tags_color;
COLOR header_color;
COLOR volume_color;

View File

@@ -299,9 +299,8 @@ void Window::Write(int limit, const string &str, CLEAR_TO_EOL clrtoeol)
tmp.clear();
if (is_valid_color(color))
{
const COLOR *colors = into_color(color);
SetColor(colors[0],colors[1]);
delete [] colors;
std::pair<COLOR, COLOR> colors = into_color(color);
SetColor(colors.first, colors.second);
}
else
{
@@ -361,11 +360,10 @@ void Window::Write(int limit, const wstring &str, CLEAR_TO_EOL clrtoeol)
{
waddwstr(itsWindow,tmp.c_str());
tmp.clear();
if (is_valid_color(ToString(color.c_str())))
if (is_valid_color(ToString(color)))
{
const COLOR *colors = into_color(ToString(color.c_str()));
SetColor(colors[0],colors[1]);
delete [] colors;
std::pair<COLOR, COLOR> colors = into_color(ToString(color));
SetColor(colors.first, colors.second);
}
else
{

View File

@@ -23,6 +23,7 @@
#include "ncurses.h"
#include <stack>
#include <vector>
#include <string>
#include <cstdlib>
@@ -117,7 +118,7 @@ class Window
virtual bool reallocate_win(int, int);
virtual void recreate_win();
virtual void show_border() const;
virtual const COLOR * into_color(const string &) const;
virtual std::pair<COLOR, COLOR> into_color(const string &);
//bool is_valid_color(const string &);
WINDOW *itsWindow;
WINDOW *itsWinBorder;
@@ -128,6 +129,7 @@ class Window
bool BBEnabled;
bool AutoRefreshEnabled;
string itsTitle;
std::stack< std::pair<COLOR, COLOR> > itsColors;
COLOR itsColor;
COLOR itsBaseColor;
COLOR itsBgColor;