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 ***************************************************************************/
27 #include "statusbar.h"
28 #include "utility/functional.h"
30 const MPD::Song
*currentSong(const BaseScreen
*screen
)
32 const MPD::Song
*ptr
= nullptr;
33 const auto *list
= dynamic_cast<const SongList
*>(screen
->activeWindow());
36 const auto it
= list
->currentS();
37 if (it
!= list
->endS())
43 MPD::SongIterator
getDatabaseIterator(MPD::Connection
&mpd
)
45 MPD::SongIterator result
;
48 result
= mpd
.GetDirectoryRecursive("/");
50 catch (MPD::ClientError
&e
)
52 if (e
.code() == MPD_ERROR_CLOSED
)
54 // If we can't get the database, display appropriate
55 // error message and reconnect with the MPD server.
56 Statusbar::print("Unable to fetch the data, increase max_output_buffer_size in your MPD configuration file");
66 void removeSongFromPlaylist(const SongMenu
&playlist
, const MPD::Song
&s
)
68 Mpd
.StartCommandsList();
69 for (auto &item
: reverse_iteration(playlist
))
70 if (item
.value() == s
)
71 Mpd
.Delete(item
.value().getPosition());
72 Mpd
.CommitCommandsList();
75 bool addSongToPlaylist(const MPD::Song
&s
, bool play
, int position
)
78 if (Config
.space_add_mode
== SpaceAddMode::AddRemove
79 && myPlaylist
->checkForSong(s
)
85 const auto begin
= myPlaylist
->main().beginV(), end
= myPlaylist
->main().endV();
86 auto it
= find_map_first(begin
, end
, s
, [](const MPD::Song
&found
) {
87 Mpd
.PlayID(found
.getID());
92 removeSongFromPlaylist(myPlaylist
->main(), s
);
95 int id
= Mpd
.AddSong(s
, position
);
98 Statusbar::printf("Added to playlist: %s",
99 Format::stringify
<char>(Config
.song_status_format
, &s
)
108 std::string
timeFormat(const char *format
, time_t t
)
112 localtime_r(&t
, &tinfo
);
113 strftime(result
, sizeof(result
), format
, &tinfo
);
117 std::string
Timestamp(time_t t
)
121 result
[strftime(result
, 31, "%x %X", localtime_r(&t
, &info
))] = 0;
125 std::wstring
Scroller(const std::wstring
&str
, size_t &pos
, size_t width
)
128 if (!Config
.header_text_scrolling
)
131 size_t len
= wideLength(s
);
137 auto b
= s
.begin(), e
= s
.end();
138 for (auto it
= b
+pos
; it
< e
&& len
< width
; ++it
)
140 if ((len
+= wcwidth(*it
)) > width
)
144 if (++pos
>= s
.length())
146 for (; len
< width
; ++b
)
148 if ((len
+= wcwidth(*b
)) > width
)
158 void writeCyclicBuffer(const NC::WBuffer
&buf
, NC::Window
&w
, size_t &start_pos
,
159 size_t width
, const std::wstring
&separator
)
161 const auto &s
= buf
.str();
162 size_t len
= wideLength(s
);
166 const auto &ps
= buf
.properties();
169 // load attributes from before starting pos
170 for (; p
!= ps
.end() && p
->first
< start_pos
; ++p
)
173 auto write_buffer
= [&](size_t start
) {
174 for (size_t i
= start
; i
< s
.length() && len
< width
; ++i
)
176 for (; p
!= ps
.end() && p
->first
== i
; ++p
)
178 len
+= wcwidth(s
[i
]);
183 for (; p
!= ps
.end(); ++p
)
188 write_buffer(start_pos
);
190 if (start_pos
> s
.length())
191 i
= start_pos
- s
.length();
192 for (; i
< separator
.length() && len
< width
; ++i
)
194 len
+= wcwidth(separator
[i
]);
202 if (start_pos
>= s
.length() + separator
.length())