1 /***************************************************************************
2 * Copyright (C) 2008-2010 by Andrzej Rybczak *
3 * electricityispower@gmail.com *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
19 ***************************************************************************/
26 std::string
Display::Columns()
28 if (Config
.columns
.empty())
31 std::string result
, tag
;
35 std::vector
<Column
>::const_iterator next2last
;
36 bool last_fixed
= Config
.columns
.back().fixed
;
37 if (Config
.columns
.size() > 1)
38 next2last
= Config
.columns
.end()-2;
40 for (std::vector
<Column
>::const_iterator it
= Config
.columns
.begin(); it
!= Config
.columns
.end(); ++it
)
42 if (it
== Config
.columns
.end()-1)
44 else if (last_fixed
&& it
== next2last
)
45 width
= COLS
-where
-(++next2last
)->width
;
47 width
= it
->width
*(it
->fixed
? 1 : COLS
/100.0);
98 if (it
->right_alignment
)
100 long i
= width
-tag
.length()-(it
!= Config
.columns
.begin());
102 result
+= std::string(i
, ' ');
108 if (result
.length() > where
)
109 result
= result
.substr(0, where
);
111 for (size_t i
= result
.length(); i
<= where
&& i
< size_t(COLS
); ++i
, result
+= ' ') { }
116 void Display::SongsInColumns(const MPD::Song
&s
, void *, Menu
<MPD::Song
> *menu
)
119 const_cast<MPD::Song
*>(&s
)->Localize();
121 bool is_now_playing
= menu
== myPlaylist
->Items
&& (menu
->isFiltered() ? s
.GetPosition() : menu
->CurrentlyDrawedPosition()) == size_t(myPlaylist
->NowPlaying
);
123 *menu
<< Config
.now_playing_prefix
;
125 if (Config
.columns
.empty())
128 std::vector
<Column
>::const_iterator next2last
, last
, it
;
132 bool last_fixed
= Config
.columns
.back().fixed
;
133 if (Config
.columns
.size() > 1)
134 next2last
= Config
.columns
.end()-2;
135 last
= Config
.columns
.end()-1;
137 bool discard_colors
= Config
.discard_colors_if_item_is_selected
&& menu
->isSelected(menu
->CurrentlyDrawedPosition());
139 for (it
= Config
.columns
.begin(); it
!= Config
.columns
.end(); ++it
)
143 menu
->GotoXY(where
, menu
->Y());
145 if (!discard_colors
&& (it
-1)->color
!= clDefault
)
149 if (it
== Config
.columns
.end()-1)
150 width
= menu
->GetWidth()-where
;
151 else if (last_fixed
&& it
== next2last
)
152 width
= COLS
-where
-(++next2last
)->width
;
154 width
= it
->width
*(it
->fixed
? 1 : COLS
/100.0);
156 MPD::Song::GetFunction get
= 0;
161 get
= &MPD::Song::GetLength
;
164 get
= &MPD::Song::GetDirectory
;
167 get
= &MPD::Song::GetName
;
170 get
= &MPD::Song::GetArtist
;
173 get
= &MPD::Song::GetAlbumArtist
;
176 get
= &MPD::Song::GetAlbum
;
179 get
= &MPD::Song::GetDate
;
182 get
= &MPD::Song::GetTrackNumber
;
185 get
= &MPD::Song::GetTrack
;
188 get
= &MPD::Song::GetGenre
;
191 get
= &MPD::Song::GetComposer
;
194 get
= &MPD::Song::GetPerformer
;
197 get
= &MPD::Song::GetDisc
;
200 get
= &MPD::Song::GetComment
;
203 if (!s
.GetTitle().empty())
204 get
= &MPD::Song::GetTitle
;
206 get
= &MPD::Song::GetName
;
211 if (!discard_colors
&& it
->color
!= clDefault
)
213 whline(menu
->Raw(), 32, menu
->GetWidth()-where
);
214 std::string tag
= get
? s
.GetTags(get
) : "";
216 // last column might need to be shrinked to make space for np/sel suffixes
219 if (menu
->isSelected(menu
->CurrentlyDrawedPosition()))
220 width
-= Config
.selected_item_suffix_length
;
222 width
-= Config
.now_playing_suffix_length
;
225 if (it
->right_alignment
)
227 if (width
> 0 && (!tag
.empty() || it
->display_empty_tag
))
231 std::basic_string
<my_char_t
> wtag
= TO_WSTRING(tag
.empty() ? Config
.empty_tag
: tag
).substr(0, width
-!!x
);
232 *menu
<< XY(x
+width
-Window::Length(wtag
)-!!x
, y
) << wtag
;
241 std::basic_string
<my_char_t
> str
;
243 str
= TO_WSTRING(tag
).substr(0, width
-1);
244 else if (it
->display_empty_tag
)
245 str
= TO_WSTRING(Config
.empty_tag
).substr(0, width
-1);
253 else if (it
->display_empty_tag
)
254 *menu
<< Config
.empty_tag
;
259 if (!discard_colors
&& (--it
)->color
!= clDefault
)
262 *menu
<< Config
.now_playing_suffix
;
265 void Display::Songs(const MPD::Song
&s
, void *data
, Menu
<MPD::Song
> *menu
)
268 const_cast<MPD::Song
*>(&s
)->Localize();
270 bool is_now_playing
= menu
== myPlaylist
->Items
&& (menu
->isFiltered() ? s
.GetPosition() : menu
->CurrentlyDrawedPosition()) == size_t(myPlaylist
->NowPlaying
);
272 *menu
<< Config
.now_playing_prefix
;
274 bool discard_colors
= Config
.discard_colors_if_item_is_selected
&& menu
->isSelected(menu
->CurrentlyDrawedPosition());
276 std::string line
= s
.toString(*static_cast<std::string
*>(data
), "$");
277 for (std::string::const_iterator it
= line
.begin(); it
!= line
.end(); ++it
)
281 if (++it
== line
.end()) // end of format
286 else if (isdigit(*it
)) // color
289 *menu
<< Color(*it
-'0');
291 else if (*it
== 'R') // right align
293 basic_buffer
<my_char_t
> buf
;
295 String2Buffer(TO_WSTRING(line
.substr(it
-line
.begin()+1)), buf
);
297 buf
.RemoveFormatting();
299 buf
<< Config
.now_playing_suffix
;
300 *menu
<< XY(menu
->GetWidth()-buf
.Str().length()-(menu
->isSelected(menu
->CurrentlyDrawedPosition()) ? Config
.selected_item_suffix_length
: 0), menu
->Y()) << buf
;
303 else // not a color nor right align, just a random character
306 else if (*it
== MPD::Song::FormatEscapeCharacter
)
308 // treat '$' as a normal character if song format escape char is prepended to it
309 if (++it
== line
.end() || *it
!= '$')
317 *menu
<< Config
.now_playing_suffix
;
320 void Display::Tags(const MPD::Song
&s
, void *data
, Menu
<MPD::Song
> *menu
)
322 size_t i
= static_cast<Menu
<std::string
> *>(data
)->Choice();
325 ShowTag(*menu
, s
.GetTags(Info::Tags
[i
].Get
));
329 if (s
.GetNewName().empty())
330 *menu
<< s
.GetName();
332 *menu
<< s
.GetName() << Config
.color2
<< " -> " << clEnd
<< s
.GetNewName();
336 void Display::Items(const MPD::Item
&item
, void *, Menu
<MPD::Item
> *menu
)
340 case MPD::itDirectory
:
347 *menu
<< "[" << ExtractTopDirectory(item
.name
) << "]";
351 if (!Config
.columns_in_browser
)
352 Display::Songs(*item
.song
, &Config
.song_list_format
, reinterpret_cast<Menu
<MPD::Song
> *>(menu
));
354 Display::SongsInColumns(*item
.song
, 0, reinterpret_cast<Menu
<MPD::Song
> *>(menu
));
356 case MPD::itPlaylist
:
357 *menu
<< Config
.browser_playlist_prefix
<< item
.name
;
364 void Display::SearchEngine(const std::pair
<Buffer
*, MPD::Song
*> &pair
, void *, Menu
< std::pair
<Buffer
*, MPD::Song
*> > *menu
)
368 if (!Config
.columns_in_search_engine
)
369 Display::Songs(*pair
.second
, &Config
.song_list_format
, reinterpret_cast<Menu
<MPD::Song
> *>(menu
));
371 Display::SongsInColumns(*pair
.second
, 0, reinterpret_cast<Menu
<MPD::Song
> *>(menu
));
375 *menu
<< *pair
.first
;