1 /***************************************************************************
2 * Copyright (C) 2008-2016 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 ***************************************************************************/
22 #include <boost/range/adaptor/reversed.hpp>
27 #include "screens/playlist.h"
28 #include "statusbar.h"
29 #include "utility/functional.h"
31 const MPD::Song
*currentSong(const BaseScreen
*screen
)
33 const MPD::Song
*ptr
= nullptr;
34 const auto *list
= dynamic_cast<const SongList
*>(screen
->activeWindow());
37 const auto it
= list
->currentS();
38 if (it
!= list
->endS())
44 MPD::SongIterator
getDatabaseIterator(MPD::Connection
&mpd
)
46 MPD::SongIterator result
;
49 result
= mpd
.GetDirectoryRecursive("/");
51 catch (MPD::ClientError
&e
)
53 if (e
.code() == MPD_ERROR_CLOSED
)
55 // If we can't get the database, display appropriate
56 // error message and reconnect with the MPD server.
57 Statusbar::print("Unable to fetch the data, increase max_output_buffer_size in your MPD configuration file");
67 void removeSongFromPlaylist(const SongMenu
&playlist
, const MPD::Song
&s
)
69 Mpd
.StartCommandsList();
70 for (auto &item
: boost::adaptors::reverse(playlist
))
71 if (item
.value() == s
)
72 Mpd
.Delete(item
.value().getPosition());
73 Mpd
.CommitCommandsList();
76 bool addSongToPlaylist(const MPD::Song
&s
, bool play
, int position
)
79 if (Config
.space_add_mode
== SpaceAddMode::AddRemove
80 && myPlaylist
->checkForSong(s
)
86 const auto begin
= myPlaylist
->main().beginV(), end
= myPlaylist
->main().endV();
87 auto it
= find_map_first(begin
, end
, s
, [](const MPD::Song
&found
) {
88 Mpd
.PlayID(found
.getID());
93 removeSongFromPlaylist(myPlaylist
->main(), s
);
96 int id
= Mpd
.AddSong(s
, position
);
99 Statusbar::printf("Added to playlist: %s",
100 Format::stringify
<char>(Config
.song_status_format
, &s
)
109 std::string
timeFormat(const char *format
, time_t t
)
113 localtime_r(&t
, &tinfo
);
114 strftime(result
, sizeof(result
), format
, &tinfo
);
118 std::string
Timestamp(time_t t
)
122 result
[strftime(result
, 31, "%x %X", localtime_r(&t
, &info
))] = 0;
126 std::wstring
Scroller(const std::wstring
&str
, size_t &pos
, size_t width
)
129 if (!Config
.header_text_scrolling
)
132 size_t len
= wideLength(s
);
138 auto b
= s
.begin(), e
= s
.end();
139 for (auto it
= b
+pos
; it
< e
&& len
< width
; ++it
)
141 if ((len
+= wcwidth(*it
)) > width
)
145 if (++pos
>= s
.length())
147 for (; len
< width
; ++b
)
149 if ((len
+= wcwidth(*b
)) > width
)
159 void writeCyclicBuffer(const NC::WBuffer
&buf
, NC::Window
&w
, size_t &start_pos
,
160 size_t width
, const std::wstring
&separator
)
162 const auto &s
= buf
.str();
163 size_t len
= wideLength(s
);
167 const auto &ps
= buf
.properties();
170 // load attributes from before starting pos
171 for (; p
!= ps
.end() && p
->first
< start_pos
; ++p
)
174 auto write_buffer
= [&](size_t start
) {
175 for (size_t i
= start
; i
< s
.length() && len
< width
; ++i
)
177 for (; p
!= ps
.end() && p
->first
== i
; ++p
)
179 len
+= wcwidth(s
[i
]);
184 for (; p
!= ps
.end(); ++p
)
189 write_buffer(start_pos
);
191 if (start_pos
> s
.length())
192 i
= start_pos
- s
.length();
193 for (; i
< separator
.length() && len
< width
; ++i
)
195 len
+= wcwidth(separator
[i
]);
203 if (start_pos
>= s
.length() + separator
.length())