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 Replace(now_playing_format
, "\\n", "\n");
160 Replace(now_playing_format
, "\\t", "\t");
161 MPD::Song::ValidateFormat("now-playing format", now_playing_format
);
163 std::cout
<< utf_to_locale_cpy(Mpd
.GetCurrentSong().toString(now_playing_format
)) << "\n";
167 else if (!strcmp(argv
[i
], "play"))
172 else if (!strcmp(argv
[i
], "pause"))
177 else if (!strcmp(argv
[i
], "toggle"))
182 else if (!strcmp(argv
[i
], "stop"))
187 else if (!strcmp(argv
[i
], "next"))
192 else if (!strcmp(argv
[i
], "prev"))
197 else if (!strcmp(argv
[i
], "volume"))
201 if (!Mpd
.GetErrorMessage().empty())
203 std::cout
<< "Error: " << Mpd
.GetErrorMessage() << std::endl
;
207 Mpd
.SetVolume(Mpd
.GetVolume()+atoi(argv
[i
]));
212 std::cout
<< "ncmpcpp: invalid option: " << argv
[i
] << std::endl
;
215 if (!Mpd
.GetErrorMessage().empty())
217 std::cout
<< "Error: " << Mpd
.GetErrorMessage() << std::endl
;
225 bool CaseInsensitiveSorting::operator()(const Item
&a
, const Item
&b
)
227 if (a
.type
== b
.type
)
232 return cmp(ExtractTopDirectory(a
.name
), ExtractTopDirectory(b
.name
)) < 0;
234 return cmp(a
.name
, b
.name
) < 0;
236 return Config
.browser_sort_by_mtime
237 ? a
.song
->GetMTime() > b
.song
->GetMTime()
238 : operator()(a
.song
, b
.song
);
239 default: // there's no other type, just silence compiler.
244 return a
.type
< b
.type
;
247 std::string
Timestamp(time_t t
)
251 result
[strftime(result
, 31, "%x %X", localtime_r(&t
, &info
))] = 0;
255 void UpdateSongList(Menu
<Song
> *menu
)
258 for (size_t i
= 0; i
< menu
->Size(); ++i
)
260 for (size_t j
= 0; j
< myPlaylist
->Items
->Size(); ++j
)
262 if (myPlaylist
->Items
->at(j
).GetHash() == menu
->at(i
).GetHash())
275 std::string
FindSharedDir(Menu
<Song
> *menu
)
278 for (size_t i
= 0; i
< menu
->Size(); ++i
)
279 list
.push_back(&(*menu
)[i
]);
280 return FindSharedDir(list
);
283 std::string
FindSharedDir(const SongList
&v
)
285 if (v
.empty()) // this should never happen, but in case...
286 FatalError("empty SongList passed to FindSharedDir(const SongList &)!");
288 std::string first
= v
.front()->GetDirectory();
289 for (SongList::const_iterator it
= ++v
.begin(); it
!= v
.end(); ++it
)
292 std::string dir
= (*it
)->GetDirectory();
293 size_t length
= std::min(first
.length(), dir
.length());
294 while (!first
.compare(j
, 1, dir
, j
, 1) && j
< length
&& j
< i
)
298 return i
? first
.substr(0, i
) : "/";
300 #endif // HAVE_TAGLIB_H
302 std::string
FindSharedDir(const std::string
&one
, const std::string
&two
)
307 while (!one
.compare(i
, 1, two
, i
, 1))
309 i
= one
.rfind("/", i
);
310 return i
!= std::string::npos
? one
.substr(0, i
) : "/";
313 std::string
GetLineValue(std::string
&line
, char a
, char b
, bool once
)
315 int pos
[2] = { -1, -1 };
317 for (i
= line
.find(a
); i
!= std::string::npos
&& pos
[1] < 0; i
= line
.find(b
, i
))
319 if (i
&& line
[i
-1] == '\\')
326 pos
[pos
[0] >= 0] = i
++;
329 std::string result
= pos
[0] >= 0 && pos
[1] >= 0 ? line
.substr(pos
[0], pos
[1]-pos
[0]) : "";
330 Replace(result
, "\\\"", "\"");
334 std::string
ExtractTopDirectory(const std::string
&s
)
336 size_t slash
= s
.rfind("/");
337 return slash
!= std::string::npos
? s
.substr(++slash
) : s
;
340 std::basic_string
<my_char_t
> Scroller(const std::basic_string
<my_char_t
> &str
, size_t &pos
, size_t width
)
342 std::basic_string
<my_char_t
> s(str
);
343 if (!Config
.header_text_scrolling
)
345 std::basic_string
<my_char_t
> result
;
346 size_t len
= Window::Length(s
);
352 std::basic_string
<my_char_t
>::const_iterator b
= s
.begin(), e
= s
.end();
353 for (std::basic_string
<my_char_t
>::const_iterator it
= b
+pos
; it
< e
&& len
< width
; ++it
)
355 if ((len
+= wcwidth(*it
)) > width
)
359 if (++pos
>= s
.length())
361 for (; len
< width
; ++b
)
363 if ((len
+= wcwidth(*b
)) > width
)
373 #ifdef HAVE_CURL_CURL_H
374 size_t write_data(char *buffer
, size_t size
, size_t nmemb
, void *data
)
376 size_t result
= size
*nmemb
;
377 static_cast<std::string
*>(data
)->append(buffer
, result
);
380 #endif // HAVE_CURL_CURL_H