1 /***************************************************************************
2 * Copyright (C) 2008-2014 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 ***************************************************************************/
21 #include <boost/bind.hpp>
29 #include "sel_items_adder.h"
31 #include "statusbar.h"
32 #include "utility/comparators.h"
33 #include "screen_switcher.h"
36 SelectedItemsAdder
*mySelectedItemsAdder
;
40 void DisplayComponent(SelectedItemsAdder::Component
&menu
)
42 menu
<< Charset::utf8ToLocale(menu
.drawn()->value().item());
47 SelectedItemsAdder::SelectedItemsAdder()
49 using Global::MainHeight
;
50 using Global::MainStartY
;
53 m_playlist_selector
= Component(
54 (COLS
-m_playlist_selector_width
)/2,
55 MainStartY
+(MainHeight
-m_playlist_selector_height
)/2,
56 m_playlist_selector_width
,
57 m_playlist_selector_height
,
58 "Add selected item(s) to...",
62 m_playlist_selector
.cyclicScrolling(Config
.use_cyclic_scrolling
);
63 m_playlist_selector
.centeredCursor(Config
.centered_cursor
);
64 m_playlist_selector
.setHighlightColor(Config
.main_highlight_color
);
65 m_playlist_selector
.setItemDisplayer(DisplayComponent
);
67 m_position_selector
= Component(
68 (COLS
-m_position_selector_width
)/2,
69 MainStartY
+(MainHeight
-m_position_selector_height
)/2,
70 m_position_selector_width
,
71 m_position_selector_height
,
76 m_position_selector
.cyclicScrolling(Config
.use_cyclic_scrolling
);
77 m_position_selector
.centeredCursor(Config
.centered_cursor
);
78 m_position_selector
.setHighlightColor(Config
.main_highlight_color
);
79 m_position_selector
.setItemDisplayer(DisplayComponent
);
81 m_position_selector
.addItem(Entry("At the end of playlist",
82 boost::bind(&Self::addAtTheEndOfPlaylist
, this)
84 m_position_selector
.addItem(Entry("At the beginning of playlist",
85 boost::bind(&Self::addAtTheBeginningOfPlaylist
, this)
87 m_position_selector
.addItem(Entry("After current song",
88 boost::bind(&Self::addAfterCurrentSong
, this)
90 m_position_selector
.addItem(Entry("After current album",
91 boost::bind(&Self::addAfterCurrentAlbum
, this)
93 m_position_selector
.addItem(Entry("After highlighted item",
94 boost::bind(&Self::addAfterHighlightedSong
, this)
96 m_position_selector
.addSeparator();
97 m_position_selector
.addItem(Entry("Cancel",
98 boost::bind(&Self::cancel
, this)
101 w
= &m_playlist_selector
;
104 void SelectedItemsAdder::switchTo()
106 using Global::myScreen
;
108 auto hs
= hasSongs(myScreen
);
109 if (!hs
|| !hs
->allowsSelection())
112 Statusbar::print(1, "Fetching selected songs...");
113 m_selected_items
= hs
->getSelectedSongs();
114 if (m_selected_items
.empty())
116 Statusbar::print("List of selected items is empty");
119 populatePlaylistSelector(myScreen
);
120 SwitchTo::execute(this);
121 // default to main window
122 w
= &m_playlist_selector
;
125 void SelectedItemsAdder::resize()
127 using Global::MainHeight
;
128 using Global::MainStartY
;
130 m_playlist_selector
.resize(m_playlist_selector_width
, m_playlist_selector_height
);
131 m_playlist_selector
.moveTo(
132 (COLS
-m_playlist_selector_width
)/2,
133 MainStartY
+(MainHeight
-m_playlist_selector_height
)/2
135 m_position_selector
.resize(m_position_selector_width
, m_position_selector_height
);
136 m_position_selector
.moveTo(
137 (COLS
-m_position_selector_width
)/2,
138 MainStartY
+(MainHeight
-m_position_selector_height
)/2
140 if (previousScreen() && previousScreen()->hasToBeResized
) // resize background window
142 previousScreen()->resize();
143 previousScreen()->refresh();
148 void SelectedItemsAdder::refresh()
150 if (isActiveWindow(m_position_selector
))
152 m_playlist_selector
.display();
153 m_position_selector
.display();
155 else if (isActiveWindow(m_playlist_selector
))
156 m_playlist_selector
.display();
159 std::wstring
SelectedItemsAdder::title()
161 return previousScreen()->title();
164 void SelectedItemsAdder::enterPressed()
166 w
->current().value().run();
169 void SelectedItemsAdder::mouseButtonPressed(MEVENT me
)
171 if (w
->empty() || !w
->hasCoords(me
.x
, me
.y
) || size_t(me
.y
) >= w
->size())
173 if (me
.bstate
& (BUTTON1_PRESSED
| BUTTON3_PRESSED
))
176 if (me
.bstate
& BUTTON3_PRESSED
)
180 Screen
<WindowType
>::mouseButtonPressed(me
);
183 void SelectedItemsAdder::populatePlaylistSelector(BaseScreen
*old_screen
)
185 // stored playlists don't support songs from outside of mpd database
186 bool in_local_browser
= old_screen
== myBrowser
&& myBrowser
->isLocal();
188 m_playlist_selector
.reset();
189 m_playlist_selector
.clear();
190 m_playlist_selector
.addItem(Entry("Current playlist",
191 boost::bind(&Self::addToCurrentPlaylist
, this)
193 if (!in_local_browser
)
195 m_playlist_selector
.addItem(Entry("New playlist",
196 boost::bind(&Self::addToNewPlaylist
, this)
199 m_playlist_selector
.addSeparator();
200 if (!in_local_browser
)
202 size_t begin
= m_playlist_selector
.size();
203 Mpd
.GetPlaylists([this](std::string playlist
) {
204 m_playlist_selector
.addItem(Entry(playlist
,
205 boost::bind(&Self::addToExistingPlaylist
, this, playlist
)
208 std::sort(m_playlist_selector
.beginV()+begin
, m_playlist_selector
.endV(),
209 LocaleBasedSorting(std::locale(), Config
.ignore_leading_the
));
210 if (begin
< m_playlist_selector
.size())
211 m_playlist_selector
.addSeparator();
213 m_playlist_selector
.addItem(Entry("Cancel",
214 boost::bind(&Self::cancel
, this)
218 void SelectedItemsAdder::addToCurrentPlaylist()
220 w
= &m_position_selector
;
221 m_position_selector
.reset();
224 void SelectedItemsAdder::addToNewPlaylist() const
227 Statusbar::put() << "Save playlist as: ";
228 std::string playlist
= Global::wFooter
->getString();
230 if (!playlist
.empty())
231 addToExistingPlaylist(playlist
);
234 void SelectedItemsAdder::addToExistingPlaylist(const std::string
&playlist
) const
236 Mpd
.StartCommandsList();
237 for (auto s
= m_selected_items
.begin(); s
!= m_selected_items
.end(); ++s
)
238 Mpd
.AddToPlaylist(playlist
, *s
);
239 Mpd
.CommitCommandsList();
240 Statusbar::printf("Selected item(s) added to playlist \"%1%\"", playlist
);
241 switchToPreviousScreen();
244 void SelectedItemsAdder::addAtTheEndOfPlaylist() const
246 bool success
= addSongsToPlaylist(m_selected_items
.begin(), m_selected_items
.end(), false, -1);
247 exitSuccessfully(success
);
250 void SelectedItemsAdder::addAtTheBeginningOfPlaylist() const
252 bool success
= addSongsToPlaylist(m_selected_items
.begin(), m_selected_items
.end(), false, 0);
253 exitSuccessfully(success
);
256 void SelectedItemsAdder::addAfterCurrentSong() const
258 if (Status::State::player() == MPD::psStop
)
260 size_t pos
= Status::State::currentSongPosition();
262 bool success
= addSongsToPlaylist(m_selected_items
.begin(), m_selected_items
.end(), false, pos
);
263 exitSuccessfully(success
);
266 void SelectedItemsAdder::addAfterCurrentAlbum() const
268 if (Status::State::player() == MPD::psStop
)
270 auto &pl
= myPlaylist
->main();
271 size_t pos
= Status::State::currentSongPosition();
272 withUnfilteredMenu(pl
, [&pos
, &pl
]() {
273 std::string album
= pl
[pos
].value().getAlbum();
274 while (pos
< pl
.size() && pl
[pos
].value().getAlbum() == album
)
277 bool success
= addSongsToPlaylist(m_selected_items
.begin(), m_selected_items
.end(), false, pos
);
278 exitSuccessfully(success
);
281 void SelectedItemsAdder::addAfterHighlightedSong() const
283 size_t pos
= myPlaylist
->main().current().value().getPosition();
285 bool success
= addSongsToPlaylist(m_selected_items
.begin(), m_selected_items
.end(), false, pos
);
286 exitSuccessfully(success
);
289 void SelectedItemsAdder::cancel()
291 if (isActiveWindow(m_playlist_selector
))
292 switchToPreviousScreen();
293 else if (isActiveWindow(m_position_selector
))
294 w
= &m_playlist_selector
;
297 void SelectedItemsAdder::exitSuccessfully(bool success
) const
299 Statusbar::printf("Selected items added%1%", withErrors(success
));
300 switchToPreviousScreen();
303 void SelectedItemsAdder::setDimensions()
305 using Global::MainHeight
;
307 m_playlist_selector_width
= COLS
*0.6;
308 m_playlist_selector_height
= std::min(MainHeight
, size_t(LINES
*0.66));
310 m_position_selector_width
= std::min(size_t(35), size_t(COLS
));
311 m_position_selector_height
= std::min(size_t(11), MainHeight
);