1 /***************************************************************************
2 * Copyright (C) 2008-2009 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 ***************************************************************************/
31 #include "tag_editor.h"
39 std::cout
<< "Cannot connect to mpd: " << Mpd
.GetErrorMessage() << std::endl
;
45 void ParseArgv(int argc
, char **argv
)
48 std::string now_playing_format
= "{{(%l) }{{%a - }%t}}|{%f}}";
50 for (int i
= 1; i
< argc
; ++i
)
52 if (!strcmp(argv
[i
], "-h") || !strcmp(argv
[i
], "--host"))
56 Mpd
.SetHostname(argv
[i
]);
59 if (!strcmp(argv
[i
], "-p") || !strcmp(argv
[i
], "--port"))
63 Mpd
.SetPort(atoi(argv
[i
]));
66 else if (!strcmp(argv
[i
], "-v") || !strcmp(argv
[i
], "--version"))
68 std::cout
<< "ncmpcpp version: " << VERSION
<< "\n\n"
69 << "optional screens compiled-in:\n"
72 << " - tiny tag editor\n"
74 # ifdef HAVE_CURL_CURL_H
77 # ifdef ENABLE_OUTPUTS
80 # ifdef ENABLE_VISUALIZER
86 << "\nencoding detection: "
87 # ifdef HAVE_LANGINFO_H
91 # endif // HAVE_LANGINFO_H
92 << "\nbuilt with support for:"
93 # ifdef HAVE_CURL_CURL_H
107 # ifdef HAVE_TAGLIB_H
110 # ifdef HAVE_PTHREAD_H
119 else if (!strcmp(argv
[i
], "-?") || !strcmp(argv
[i
], "--help"))
122 << "Usage: ncmpcpp [OPTION]...\n"
123 << " -h, --host connect to server at host [localhost]\n"
124 << " -p, --port connect to server at port [6600]\n"
125 << " -?, --help show this help message\n"
126 << " -v, --version display version information\n"
127 << " --now-playing display now playing song [" << now_playing_format
<< "]\n"
129 << " play start playing\n"
130 << " pause pause the currently playing song\n"
131 << " toggle toggle play/pause mode\n"
132 << " stop stop playing\n"
133 << " next play the next song\n"
134 << " prev play the previous song\n"
135 << " volume [+-]<num> adjusts volume by [+-]<num>\n"
143 if (!strcmp(argv
[i
], "--now-playing"))
146 if (!Mpd
.GetErrorMessage().empty())
148 std::cout
<< "Error: " << Mpd
.GetErrorMessage() << std::endl
;
155 // apply additional pair of braces
156 now_playing_format
= "{";
157 now_playing_format
+= argv
[i
];
158 now_playing_format
+= "}";
159 MPD::Song::ValidateFormat("now-playing format", now_playing_format
);
161 std::cout
<< utf_to_locale_cpy(Mpd
.GetCurrentSong().toString(now_playing_format
)) << "\n";
165 else if (!strcmp(argv
[i
], "play"))
170 else if (!strcmp(argv
[i
], "pause"))
175 else if (!strcmp(argv
[i
], "toggle"))
180 else if (!strcmp(argv
[i
], "stop"))
185 else if (!strcmp(argv
[i
], "next"))
190 else if (!strcmp(argv
[i
], "prev"))
195 else if (!strcmp(argv
[i
], "volume"))
199 if (!Mpd
.GetErrorMessage().empty())
201 std::cout
<< "Error: " << Mpd
.GetErrorMessage() << std::endl
;
205 Mpd
.SetVolume(Mpd
.GetVolume()+atoi(argv
[i
]));
210 std::cout
<< "ncmpcpp: invalid option: " << argv
[i
] << std::endl
;
213 if (!Mpd
.GetErrorMessage().empty())
215 std::cout
<< "Error: " << Mpd
.GetErrorMessage() << std::endl
;
223 bool CaseInsensitiveSorting::operator()(const Item
&a
, const Item
&b
)
225 if (a
.type
== b
.type
)
230 return cmp(ExtractTopDirectory(a
.name
), ExtractTopDirectory(b
.name
)) < 0;
232 return cmp(a
.name
, b
.name
) < 0;
234 return operator()(a
.song
, b
.song
);
235 default: // there's no other type, just silence compiler.
240 return a
.type
< b
.type
;
243 void UpdateSongList(Menu
<Song
> *menu
)
246 for (size_t i
= 0; i
< menu
->Size(); ++i
)
248 for (size_t j
= 0; j
< myPlaylist
->Items
->Size(); ++j
)
250 if (myPlaylist
->Items
->at(j
).GetHash() == menu
->at(i
).GetHash())
263 std::string
FindSharedDir(Menu
<Song
> *menu
)
266 for (size_t i
= 0; i
< menu
->Size(); ++i
)
267 list
.push_back(&(*menu
)[i
]);
268 return FindSharedDir(list
);
271 std::string
FindSharedDir(const SongList
&v
)
273 if (v
.empty()) // this should never happen, but in case...
274 FatalError("empty SongList passed to FindSharedDir(const SongList &)!");
276 std::string first
= v
.front()->GetDirectory();
277 for (SongList::const_iterator it
= ++v
.begin(); it
!= v
.end(); ++it
)
280 std::string dir
= (*it
)->GetDirectory();
281 size_t length
= std::min(first
.length(), dir
.length());
282 while (!first
.compare(j
, 1, dir
, j
, 1) && j
< length
&& j
< i
)
286 return i
? first
.substr(0, i
) : "/";
288 #endif // HAVE_TAGLIB_H
290 std::string
FindSharedDir(const std::string
&one
, const std::string
&two
)
295 while (!one
.compare(i
, 1, two
, i
, 1))
297 i
= one
.rfind("/", i
);
298 return i
!= std::string::npos
? one
.substr(0, i
) : "/";
301 std::string
GetLineValue(std::string
&line
, char a
, char b
, bool once
)
303 int pos
[2] = { -1, -1 };
305 for (i
= line
.find(a
); i
!= std::string::npos
&& pos
[1] < 0; i
= line
.find(b
, i
))
307 if (i
&& line
[i
-1] == '\\')
314 pos
[pos
[0] >= 0] = i
++;
317 std::string result
= pos
[0] >= 0 && pos
[1] >= 0 ? line
.substr(pos
[0], pos
[1]-pos
[0]) : "";
318 for (i
= result
.find("\\\""); i
!= std::string::npos
; i
= result
.find("\\\""))
319 result
.replace(i
, 2, "\"");
323 std::string
ExtractTopDirectory(const std::string
&s
)
325 size_t slash
= s
.rfind("/");
326 return slash
!= std::string::npos
? s
.substr(++slash
) : s
;
329 std::basic_string
<my_char_t
> Scroller(const std::basic_string
<my_char_t
> &str
, size_t &pos
, size_t width
)
331 std::basic_string
<my_char_t
> s(str
);
332 if (!Config
.header_text_scrolling
)
334 std::basic_string
<my_char_t
> result
;
335 size_t len
= Window::Length(s
);
341 std::basic_string
<my_char_t
>::const_iterator b
= s
.begin(), e
= s
.end();
342 for (std::basic_string
<my_char_t
>::const_iterator it
= b
+pos
; it
< e
&& len
< width
; ++it
)
344 if ((len
+= wcwidth(*it
)) > width
)
348 if (++pos
>= s
.length())
350 for (; len
< width
; ++b
)
352 if ((len
+= wcwidth(*b
)) > width
)
362 #ifdef HAVE_CURL_CURL_H
363 size_t write_data(char *buffer
, size_t size
, size_t nmemb
, void *data
)
365 size_t result
= size
*nmemb
;
366 static_cast<std::string
*>(data
)->append(buffer
, result
);
369 #endif // HAVE_CURL_CURL_H