more cleanup and grouping functions logically together

This commit is contained in:
Andrzej Rybczak
2012-08-29 14:34:39 +02:00
parent b1c301dc1c
commit b06e620913
28 changed files with 486 additions and 512 deletions

View File

@@ -3,11 +3,11 @@ ncmpcpp_SOURCES = \
utility/comparators.cpp \
utility/html.cpp \
utility/string.cpp \
utility/type_conversions.cpp \
actions.cpp \
browser.cpp \
charset.cpp \
clock.cpp \
conv.cpp \
curl_handle.cpp \
display.cpp \
error.cpp \
@@ -49,10 +49,11 @@ noinst_HEADERS = \
utility/comparators.h \
utility/html.h \
utility/string.h \
utility/numeric_conversions.h \
utility/type_conversions.h \
browser.h \
charset.h \
clock.h \
conv.h \
curl_handle.h \
display.h \
error.h \
@@ -68,7 +69,6 @@ noinst_HEADERS = \
menu.h \
mpdpp.h \
mutable_song.h \
numeric_conversions.h \
outputs.h \
playlist_editor.h \
screen.h \

View File

@@ -20,6 +20,7 @@
#include <cassert>
#include <cerrno>
#include <cstring>
#include <iostream>
#include "actions.h"
@@ -44,6 +45,7 @@
#include "song_info.h"
#include "outputs.h"
#include "utility/string.h"
#include "utility/type_conversions.h"
#include "tag_editor.h"
#include "tiny_tag_editor.h"
#include "visualizer.h"
@@ -786,7 +788,7 @@ void Delete::Run()
if (Mpd.DeletePlaylist(locale_to_utf_cpy(name)))
{
const char msg[] = "Playlist \"%s\" deleted";
ShowMessage(msg, Shorten(TO_WSTRING(name), COLS-static_strlen(msg)).c_str());
ShowMessage(msg, Shorten(TO_WSTRING(name), COLS-const_strlen(msg)).c_str());
if (myBrowser->Main() && !myBrowser->isLocal() && myBrowser->CurrentDir() == "/")
myBrowser->GetDirectory("/");
}
@@ -844,12 +846,12 @@ void Delete::Run()
if (myBrowser->DeleteItem(it))
{
const char msg[] = "\"%s\" deleted";
ShowMessage(msg, Shorten(TO_WSTRING(name), COLS-static_strlen(msg)).c_str());
ShowMessage(msg, Shorten(TO_WSTRING(name), COLS-const_strlen(msg)).c_str());
}
else
{
const char msg[] = "Couldn't delete \"%s\": %s";
ShowMessage(msg, Shorten(TO_WSTRING(name), COLS-static_strlen(msg)-25).c_str(), strerror(errno));
ShowMessage(msg, Shorten(TO_WSTRING(name), COLS-const_strlen(msg)-25).c_str(), strerror(errno));
success = 0;
break;
}
@@ -1109,7 +1111,7 @@ void Add::Run()
else
{
const char lastfm_url[] = "lastfm://";
if (path.compare(0, static_strlen(lastfm_url), lastfm_url) == 0
if (path.compare(0, const_strlen(lastfm_url), lastfm_url) == 0
|| path.find(".asx", path.length()-4) != std::string::npos
|| path.find(".cue", path.length()-4) != std::string::npos
|| path.find(".m3u", path.length()-4) != std::string::npos
@@ -1372,7 +1374,7 @@ void SetCrossfade::Run()
Statusbar() << "Set crossfade to: ";
std::string crossfade = wFooter->GetString(3);
UnlockStatusbar();
int cf = StrToInt(crossfade);
int cf = stringToInt(crossfade);
if (cf > 0)
{
Config.crossfade_time = cf;
@@ -1419,7 +1421,7 @@ void EditLibraryTag::Run()
if (!isMPDMusicDirSet())
return;
LockStatusbar();
Statusbar() << fmtBold << IntoStr(Config.media_lib_primary_tag) << fmtBoldEnd << ": ";
Statusbar() << fmtBold << tagTypeToString(Config.media_lib_primary_tag) << fmtBoldEnd << ": ";
std::string new_tag = wFooter->GetString(myLibrary->Artists->Current());
UnlockStatusbar();
if (!new_tag.empty() && new_tag != myLibrary->Artists->Current())
@@ -1427,7 +1429,7 @@ void EditLibraryTag::Run()
ShowMessage("Updating tags...");
Mpd.StartSearch(1);
Mpd.AddSearch(Config.media_lib_primary_tag, locale_to_utf_cpy(myLibrary->Artists->Current()));
MPD::MutableSong::SetFunction set = IntoSetFunction(Config.media_lib_primary_tag);
MPD::MutableSong::SetFunction set = tagTypeToSetFunction(Config.media_lib_primary_tag);
assert(set);
bool success = true;
std::string dir_to_update;
@@ -1441,7 +1443,7 @@ void EditLibraryTag::Run()
if (!TagEditor::WriteTags(es))
{
const char msg[] = "Error while updating tags in \"%s\"";
ShowMessage(msg, Shorten(TO_WSTRING(es.getURI()), COLS-static_strlen(msg)).c_str());
ShowMessage(msg, Shorten(TO_WSTRING(es.getURI()), COLS-const_strlen(msg)).c_str());
success = false;
}
if (dir_to_update.empty())
@@ -1491,7 +1493,7 @@ void EditLibraryAlbum::Run()
if (f.isNull())
{
const char msg[] = "Error while opening file \"%s\"";
ShowMessage(msg, Shorten(TO_WSTRING((*myLibrary->Songs)[i].getURI()), COLS-static_strlen(msg)).c_str());
ShowMessage(msg, Shorten(TO_WSTRING((*myLibrary->Songs)[i].getURI()), COLS-const_strlen(msg)).c_str());
success = 0;
break;
}
@@ -1499,7 +1501,7 @@ void EditLibraryAlbum::Run()
if (!f.save())
{
const char msg[] = "Error while writing tags in \"%s\"";
ShowMessage(msg, Shorten(TO_WSTRING((*myLibrary->Songs)[i].getURI()), COLS-static_strlen(msg)).c_str());
ShowMessage(msg, Shorten(TO_WSTRING((*myLibrary->Songs)[i].getURI()), COLS-const_strlen(msg)).c_str());
success = 0;
break;
}
@@ -1553,7 +1555,7 @@ void EditDirectoryName::Run()
if (rename_result == 0)
{
const char msg[] = "Directory renamed to \"%s\"";
ShowMessage(msg, Shorten(TO_WSTRING(new_dir), COLS-static_strlen(msg)).c_str());
ShowMessage(msg, Shorten(TO_WSTRING(new_dir), COLS-const_strlen(msg)).c_str());
if (!myBrowser->isLocal())
Mpd.UpdateDirectory(locale_to_utf_cpy(getSharedDirectory(old_dir, new_dir)));
myBrowser->GetDirectory(myBrowser->CurrentDir());
@@ -1561,7 +1563,7 @@ void EditDirectoryName::Run()
else
{
const char msg[] = "Couldn't rename \"%s\": %s";
ShowMessage(msg, Shorten(TO_WSTRING(old_dir), COLS-static_strlen(msg)-25).c_str(), strerror(errno));
ShowMessage(msg, Shorten(TO_WSTRING(old_dir), COLS-const_strlen(msg)-25).c_str(), strerror(errno));
}
}
}
@@ -1580,13 +1582,13 @@ void EditDirectoryName::Run()
if (rename(full_old_dir.c_str(), full_new_dir.c_str()) == 0)
{
const char msg[] = "Directory renamed to \"%s\"";
ShowMessage(msg, Shorten(TO_WSTRING(new_dir), COLS-static_strlen(msg)).c_str());
ShowMessage(msg, Shorten(TO_WSTRING(new_dir), COLS-const_strlen(msg)).c_str());
Mpd.UpdateDirectory(myTagEditor->CurrentDir());
}
else
{
const char msg[] = "Couldn't rename \"%s\": %s";
ShowMessage(msg, Shorten(TO_WSTRING(old_dir), COLS-static_strlen(msg)-25).c_str(), strerror(errno));
ShowMessage(msg, Shorten(TO_WSTRING(old_dir), COLS-const_strlen(msg)-25).c_str(), strerror(errno));
}
}
}
@@ -1620,7 +1622,7 @@ void EditPlaylistName::Run()
if (Mpd.Rename(locale_to_utf_cpy(old_name), locale_to_utf_cpy(new_name)))
{
const char msg[] = "Playlist renamed to \"%s\"";
ShowMessage(msg, Shorten(TO_WSTRING(new_name), COLS-static_strlen(msg)).c_str());
ShowMessage(msg, Shorten(TO_WSTRING(new_name), COLS-const_strlen(msg)).c_str());
if (myBrowser->Main() && !myBrowser->isLocal())
myBrowser->GetDirectory("/");
if (myPlaylistEditor->Main())
@@ -1696,7 +1698,7 @@ void ToggleScreenLock::Run()
UnlockStatusbar();
if (str_part.empty())
return;
part = StrToInt(str_part);
part = stringToInt(str_part);
}
if (part < 20 || part > 80)
{
@@ -1760,7 +1762,7 @@ void JumpToPositionInSong::Run()
int newpos = 0;
if (position.find(':') != std::string::npos) // probably time in mm:ss
{
newpos = StrToInt(position)*60 + StrToInt(position.substr(position.find(':')+1));
newpos = stringToInt(position)*60 + stringToInt(position.substr(position.find(':')+1));
if (newpos >= 0 && newpos <= Mpd.GetTotalTime())
Mpd.Seek(newpos);
else
@@ -1768,7 +1770,7 @@ void JumpToPositionInSong::Run()
}
else if (position.find('s') != std::string::npos) // probably position in seconds
{
newpos = StrToInt(position);
newpos = stringToInt(position);
if (newpos >= 0 && newpos <= Mpd.GetTotalTime())
Mpd.Seek(newpos);
else
@@ -1776,7 +1778,7 @@ void JumpToPositionInSong::Run()
}
else
{
newpos = StrToInt(position);
newpos = stringToInt(position);
if (newpos >= 0 && newpos <= 100)
Mpd.Seek(Mpd.GetTotalTime()*newpos/100.0);
else
@@ -2163,13 +2165,13 @@ void AddRandomItems::Run()
while (answer != 's' && answer != 'a' && answer != 'b');
UnlockStatusbar();
mpd_tag_type tag_type = IntoTagItem(answer);
std::string tag_type_str = answer == 's' ? "song" : IntoStr(tag_type);
mpd_tag_type tag_type = charToTagType(answer);
std::string tag_type_str = answer == 's' ? "song" : tagTypeToString(tag_type);
lowercase(tag_type_str);
LockStatusbar();
Statusbar() << "Number of random " << tag_type_str << "s: ";
size_t number = StrToLong(wFooter->GetString());
size_t number = stringToLongInt(wFooter->GetString());
UnlockStatusbar();
if (number && (answer == 's' ? Mpd.AddRandomSongs(number) : Mpd.AddRandomTag(tag_type, number)))
ShowMessage("%zu random %s%s added to playlist", number, tag_type_str.c_str(), number == 1 ? "" : "s");
@@ -2225,11 +2227,11 @@ void ToggleLibraryTagType::Run()
}
while (answer != 'a' && answer != 'A' && answer != 'y' && answer != 'g' && answer != 'c' && answer != 'p');
UnlockStatusbar();
mpd_tag_type new_tagitem = IntoTagItem(answer);
mpd_tag_type new_tagitem = charToTagType(answer);
if (new_tagitem != Config.media_lib_primary_tag)
{
Config.media_lib_primary_tag = new_tagitem;
std::string item_type = IntoStr(Config.media_lib_primary_tag);
std::string item_type = tagTypeToString(Config.media_lib_primary_tag);
myLibrary->Artists->SetTitle(Config.titles_visibility ? item_type + "s" : "");
myLibrary->Artists->Reset();
lowercase(item_type);

View File

@@ -516,12 +516,12 @@ void Browser::ClearDirectory(const std::string &path) const
if (remove(full_path.c_str()) == 0)
{
const char msg[] = "Deleting \"%s\"...";
ShowMessage(msg, Shorten(TO_WSTRING(full_path), COLS-static_strlen(msg)).c_str());
ShowMessage(msg, Shorten(TO_WSTRING(full_path), COLS-const_strlen(msg)).c_str());
}
else
{
const char msg[] = "Couldn't remove \"%s\": %s";
ShowMessage(msg, Shorten(TO_WSTRING(full_path), COLS-static_strlen(msg)-25).c_str(), strerror(errno));
ShowMessage(msg, Shorten(TO_WSTRING(full_path), COLS-const_strlen(msg)-25).c_str(), strerror(errno));
}
}
closedir(dir);

View File

@@ -1,295 +0,0 @@
/***************************************************************************
* Copyright (C) 2008-2012 by Andrzej Rybczak *
* electricityispower@gmail.com *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#include <algorithm>
#include "conv.h"
int StrToInt(const std::string &str)
{
return atoi(str.c_str());
}
long StrToLong(const std::string &str)
{
return atol(str.c_str());
}
std::string IntoStr(mpd_tag_type tag) // this is only for left column's title in media library
{
switch (tag)
{
case MPD_TAG_ARTIST:
return "Artist";
case MPD_TAG_ALBUM:
return "Album";
case MPD_TAG_ALBUM_ARTIST:
return "Album Artist";
case MPD_TAG_TITLE:
return "Title";
case MPD_TAG_TRACK:
return "Track";
case MPD_TAG_GENRE:
return "Genre";
case MPD_TAG_DATE:
return "Date";
case MPD_TAG_COMPOSER:
return "Composer";
case MPD_TAG_PERFORMER:
return "Performer";
case MPD_TAG_COMMENT:
return "Comment";
case MPD_TAG_DISC:
return "Disc";
default:
return "";
}
}
std::string IntoStr(NCurses::Color color)
{
std::string result;
if (color == NCurses::clDefault)
result = "default";
else if (color == NCurses::clBlack)
result = "black";
else if (color == NCurses::clRed)
result = "red";
else if (color == NCurses::clGreen)
result = "green";
else if (color == NCurses::clYellow)
result = "yellow";
else if (color == NCurses::clBlue)
result = "blue";
else if (color == NCurses::clMagenta)
result = "magenta";
else if (color == NCurses::clCyan)
result = "cyan";
else if (color == NCurses::clWhite)
result = "white";
return result;
}
std::string IntoStr(const Action::Key &key, bool *print_backspace)
{
std::string result;
if (key == Action::Key(KEY_UP, ctNCurses))
result += "Up";
else if (key == Action::Key(KEY_DOWN, ctNCurses))
result += "Down";
else if (key == Action::Key(KEY_PPAGE, ctNCurses))
result += "PageUp";
else if (key == Action::Key(KEY_NPAGE, ctNCurses))
result += "PageDown";
else if (key == Action::Key(KEY_HOME, ctNCurses))
result += "Home";
else if (key == Action::Key(KEY_END, ctNCurses))
result += "End";
else if (key == Action::Key(KEY_SPACE, ctStandard))
result += "Space";
else if (key == Action::Key(KEY_ENTER, ctStandard))
result += "Enter";
else if (key == Action::Key(KEY_DC, ctNCurses))
result += "Delete";
else if (key == Action::Key(KEY_RIGHT, ctNCurses))
result += "Right";
else if (key == Action::Key(KEY_LEFT, ctNCurses))
result += "Left";
else if (key == Action::Key(KEY_TAB, ctStandard))
result += "Tab";
else if (key == Action::Key(KEY_SHIFT_TAB, ctNCurses))
result += "Shift-Tab";
else if (key >= Action::Key(KEY_CTRL_A, ctStandard) && key <= Action::Key(KEY_CTRL_Z, ctStandard))
{
result += "Ctrl-";
result += key.getChar()+64;
}
else if (key >= Action::Key(KEY_F1, ctNCurses) && key <= Action::Key(KEY_F12, ctNCurses))
{
result += "F";
result += intTo<std::string>::apply(key.getChar()-264);
}
else if ((key == Action::Key(KEY_BACKSPACE, ctNCurses) || key == Action::Key(KEY_BACKSPACE_2, ctStandard)))
{
// since some terminals interpret KEY_BACKSPACE as backspace and other need KEY_BACKSPACE_2,
// actions have to be bound to either of them, but we want to display "Backspace" only once,
// hance this 'print_backspace' switch.
if (!print_backspace || *print_backspace)
{
result += "Backspace";
if (print_backspace)
*print_backspace = false;
}
}
else
result += ToString(std::wstring(1, key.getChar()));
return result;
}
NCurses::Color IntoColor(const std::string &color)
{
NCurses::Color result = NCurses::clDefault;
if (color == "black")
result = NCurses::clBlack;
else if (color == "red")
result = NCurses::clRed;
else if (color == "green")
result = NCurses::clGreen;
else if (color == "yellow")
result = NCurses::clYellow;
else if (color == "blue")
result = NCurses::clBlue;
else if (color == "magenta")
result = NCurses::clMagenta;
else if (color == "cyan")
result = NCurses::clCyan;
else if (color == "white")
result = NCurses::clWhite;
return result;
}
mpd_tag_type IntoTagItem(char c)
{
switch (c)
{
case 'a':
return MPD_TAG_ARTIST;
case 'A':
return MPD_TAG_ALBUM_ARTIST;
case 'b':
return MPD_TAG_ALBUM;
case 'y':
return MPD_TAG_DATE;
case 'g':
return MPD_TAG_GENRE;
case 'c':
return MPD_TAG_COMPOSER;
case 'p':
return MPD_TAG_PERFORMER;
default:
return MPD_TAG_ARTIST;
}
}
MPD::Song::GetFunction toGetFunction(char c)
{
switch (c)
{
case 'l':
return &MPD::Song::getLength;
case 'D':
return &MPD::Song::getDirectory;
case 'f':
return &MPD::Song::getName;
case 'a':
return &MPD::Song::getArtist;
case 'A':
return &MPD::Song::getAlbumArtist;
case 'b':
return &MPD::Song::getAlbum;
case 'y':
return &MPD::Song::getDate;
case 'n':
return &MPD::Song::getTrackNumber;
case 'N':
return &MPD::Song::getTrack;
case 'g':
return &MPD::Song::getGenre;
case 'c':
return &MPD::Song::getComposer;
case 'p':
return &MPD::Song::getPerformer;
case 'd':
return &MPD::Song::getDisc;
case 'C':
return &MPD::Song::getComment;
case 't':
return &MPD::Song::getTitle;
case 'P':
return &MPD::Song::getPriority;
default:
return 0;
}
}
#ifdef HAVE_TAGLIB_H
MPD::MutableSong::SetFunction IntoSetFunction(mpd_tag_type tag)
{
switch (tag)
{
case MPD_TAG_ARTIST:
return &MPD::MutableSong::setArtist;
case MPD_TAG_ALBUM:
return &MPD::MutableSong::setAlbum;
case MPD_TAG_ALBUM_ARTIST:
return &MPD::MutableSong::setAlbumArtist;
case MPD_TAG_TITLE:
return &MPD::MutableSong::setTitle;
case MPD_TAG_TRACK:
return &MPD::MutableSong::setTrack;
case MPD_TAG_GENRE:
return &MPD::MutableSong::setGenre;
case MPD_TAG_DATE:
return &MPD::MutableSong::setDate;
case MPD_TAG_COMPOSER:
return &MPD::MutableSong::setComposer;
case MPD_TAG_PERFORMER:
return &MPD::MutableSong::setPerformer;
case MPD_TAG_COMMENT:
return &MPD::MutableSong::setComment;
case MPD_TAG_DISC:
return &MPD::MutableSong::setDisc;
default:
return 0;
}
}
#endif // HAVE_TAGLIB_H
std::string Shorten(const std::basic_string<my_char_t> &s, size_t max_length)
{
if (s.length() <= max_length)
return TO_STRING(s);
if (max_length < 2)
return "";
std::basic_string<my_char_t> result(s, 0, max_length/2-!(max_length%2));
result += U("..");
result += s.substr(s.length()-max_length/2+1);
return TO_STRING(result);
}
void EscapeUnallowedChars(std::string &s)
{
static const std::string unallowed_chars = "\"*/:<>?\\|";
for (std::string::const_iterator it = unallowed_chars.begin(); it != unallowed_chars.end(); ++it)
{
for (size_t i = 0; i < s.length(); ++i)
{
if (s[i] == *it)
{
s.erase(s.begin()+i);
i--;
}
}
}
}

View File

@@ -25,6 +25,7 @@
#include "song_info.h"
#include "playlist.h"
#include "global.h"
#include "utility/type_conversions.h"
using Global::myScreen;
@@ -214,7 +215,7 @@ void Display::SongsInColumns(const MPD::Song &s, void *data, Menu<MPD::Song> *me
std::basic_string<my_char_t> tag;
for (size_t i = 0; i < it->type.length(); ++i)
{
MPD::Song::GetFunction get = toGetFunction(it->type[i]);
MPD::Song::GetFunction get = charToGetFunction(it->type[i]);
tag = TO_WSTRING(get ? s.getTags(get) : "");
if (!tag.empty())
break;

View File

@@ -24,6 +24,7 @@
#include "ncmpcpp.h"
#include "menu.h"
#include "mpdpp.h"
#include "mutable_song.h"
#include "screen.h"
#include "search_engine.h"

View File

@@ -30,6 +30,66 @@ using Global::MainStartY;
Help *myHelp = new Help;
namespace {//
std::string keyToString(const Action::Key &key, bool *print_backspace)
{
std::string result;
if (key == Action::Key(KEY_UP, ctNCurses))
result += "Up";
else if (key == Action::Key(KEY_DOWN, ctNCurses))
result += "Down";
else if (key == Action::Key(KEY_PPAGE, ctNCurses))
result += "PageUp";
else if (key == Action::Key(KEY_NPAGE, ctNCurses))
result += "PageDown";
else if (key == Action::Key(KEY_HOME, ctNCurses))
result += "Home";
else if (key == Action::Key(KEY_END, ctNCurses))
result += "End";
else if (key == Action::Key(KEY_SPACE, ctStandard))
result += "Space";
else if (key == Action::Key(KEY_ENTER, ctStandard))
result += "Enter";
else if (key == Action::Key(KEY_DC, ctNCurses))
result += "Delete";
else if (key == Action::Key(KEY_RIGHT, ctNCurses))
result += "Right";
else if (key == Action::Key(KEY_LEFT, ctNCurses))
result += "Left";
else if (key == Action::Key(KEY_TAB, ctStandard))
result += "Tab";
else if (key == Action::Key(KEY_SHIFT_TAB, ctNCurses))
result += "Shift-Tab";
else if (key >= Action::Key(KEY_CTRL_A, ctStandard) && key <= Action::Key(KEY_CTRL_Z, ctStandard))
{
result += "Ctrl-";
result += key.getChar()+64;
}
else if (key >= Action::Key(KEY_F1, ctNCurses) && key <= Action::Key(KEY_F12, ctNCurses))
{
result += "F";
result += intTo<std::string>::apply(key.getChar()-264);
}
else if ((key == Action::Key(KEY_BACKSPACE, ctNCurses) || key == Action::Key(KEY_BACKSPACE_2, ctStandard)))
{
// since some terminals interpret KEY_BACKSPACE as backspace and other need KEY_BACKSPACE_2,
// actions have to be bound to either of them, but we want to display "Backspace" only once,
// hance this 'print_backspace' switch.
if (!print_backspace || *print_backspace)
{
result += "Backspace";
if (print_backspace)
*print_backspace = false;
}
}
else
result += ToString(std::wstring(1, key.getChar()));
return result;
}
}
void Help::Init()
{
w = new Scrollpad(0, MainStartY, COLS, MainHeight, "", Config.main_color, brNone);
@@ -84,7 +144,7 @@ std::string Help::DisplayKeys(const ActionType at)
{
if (it->second.isSingle() && it->second.getAction()->Type() == at)
{
result += IntoStr(it->first, &print_backspace);
result += keyToString(it->first, &print_backspace);
result += " ";
}
}

View File

@@ -353,3 +353,15 @@ std::basic_string<my_char_t> Scroller(const std::basic_string<my_char_t> &str, s
result = s;
return result;
}
std::string Shorten(const std::basic_string<my_char_t> &s, size_t max_length)
{
if (s.length() <= max_length)
return TO_STRING(s);
if (max_length < 2)
return "";
std::basic_string<my_char_t> result(s, 0, max_length/2-!(max_length%2));
result += U("..");
result += s.substr(s.length()-max_length/2+1);
return TO_STRING(result);
}

View File

@@ -21,7 +21,6 @@
#ifndef _HELPERS_H
#define _HELPERS_H
#include "conv.h"
#include "mpdpp.h"
#include "ncmpcpp.h"
#include "settings.h"
@@ -194,4 +193,6 @@ template <typename T> std::string getSharedDirectory(Menu<T> *menu)
std::basic_string<my_char_t> Scroller(const std::basic_string<my_char_t> &str, size_t &pos, size_t width);
std::string Shorten(const std::basic_string<my_char_t> &s, size_t max_length);
#endif

View File

@@ -30,6 +30,7 @@
#include <cassert>
#include <cerrno>
#include <cstring>
#include <fstream>
#include <iostream>
@@ -125,7 +126,7 @@ void Lastfm::Load()
std::string file = artist + ".txt";
lowercase(file);
EscapeUnallowedChars(file);
removeInvalidCharsFromFilename(file);
itsFilename = itsFolder + "/" + file;
@@ -211,7 +212,7 @@ void Lastfm::Refetch()
if (remove(itsFilename.c_str()) && errno != ENOENT)
{
const char msg[] = "Couldn't remove \"%s\": %s";
ShowMessage(msg, Shorten(TO_WSTRING(itsFilename), COLS-static_strlen(msg)-25).c_str(), strerror(errno));
ShowMessage(msg, Shorten(TO_WSTRING(itsFilename), COLS-const_strlen(msg)-25).c_str(), strerror(errno));
return;
}
Load();

View File

@@ -22,7 +22,6 @@
#ifdef HAVE_CURL_CURL_H
#include "conv.h"
#include "curl_handle.h"
#include "settings.h"
#include "utility/html.h"
@@ -118,7 +117,7 @@ bool ArtistInfo::parse(std::string &data)
if ((a = data.find("<content>")) != std::string::npos)
{
a += static_strlen("<content>");
a += const_strlen("<content>");
if ((b = data.find("</content>")) == std::string::npos)
parse_failed = true;
}
@@ -142,17 +141,17 @@ bool ArtistInfo::parse(std::string &data)
i != std::string::npos; i = data.find("<name>", i), k = data.find("<url>", k))
{
j = data.find("</name>", i);
i += static_strlen("<name>");
i += const_strlen("<name>");
l = data.find("</url>", k);
k += static_strlen("<url>");
k += const_strlen("<url>");
similars.push_back(std::make_pair(data.substr(i, j-i), data.substr(k, l-k)));
stripHtmlTags(similars.back().first);
}
a += static_strlen("<![CDATA[");
b -= static_strlen("]]>");
a += const_strlen("<![CDATA[");
b -= const_strlen("]]>");
data = data.substr(a, b-a);
postProcess(data);

View File

@@ -20,6 +20,7 @@
#include <cassert>
#include <cerrno>
#include <cstring>
#include <fstream>
#include "browser.h"
@@ -305,7 +306,7 @@ std::string Lyrics::GenerateFilename(const MPD::Song &s)
file += " - ";
file += locale_to_utf_cpy(s.getTitle());
file += ".txt";
EscapeUnallowedChars(file);
removeInvalidCharsFromFilename(file);
filename = Config.lyrics_directory;
filename += "/";
filename += file;
@@ -402,7 +403,7 @@ void Lyrics::Refetch()
if (remove(itsFilename.c_str()) && errno != ENOENT)
{
const char msg[] = "Couldn't remove \"%s\": %s";
ShowMessage(msg, Shorten(TO_WSTRING(itsFilename), COLS-static_strlen(msg)-25).c_str(), strerror(errno));
ShowMessage(msg, Shorten(TO_WSTRING(itsFilename), COLS-const_strlen(msg)-25).c_str(), strerror(errno));
return;
}
Load();

View File

@@ -23,11 +23,12 @@
#ifdef HAVE_CURL_CURL_H
#include <cstdlib>
#include <cstring>
#include "charset.h"
#include "conv.h"
#include "lyrics_fetcher.h"
#include "utility/html.h"
#include "utility/string.h"
LyricsFetcher *lyricsPlugins[] =
{
@@ -270,7 +271,7 @@ void LyricsvipFetcher::postProcess(std::string &data)
// throw away <div> with ad
size_t i = data.find("<div class=\"ad\""), j = data.find("</div>");
if (i != std::string::npos && i != std::string::npos)
data.replace(i, j-i+static_strlen("</div>"), "");
data.replace(i, j-i+const_strlen("</div>"), "");
data = unescapeHtmlUtf8(data);
LyricsFetcher::postProcess(data);
}

View File

@@ -30,6 +30,7 @@
#include "playlist.h"
#include "status.h"
#include "utility/comparators.h"
#include "utility/type_conversions.h"
using Global::MainHeight;
using Global::MainStartY;
@@ -60,7 +61,7 @@ void MediaLibrary::Init()
itsRightColWidth = COLS-COLS/3*2-1;
itsRightColStartX = itsLeftColWidth+itsMiddleColWidth+2;
Artists = new Menu<std::string>(0, MainStartY, itsLeftColWidth, MainHeight, Config.titles_visibility ? IntoStr(Config.media_lib_primary_tag) + "s" : "", Config.main_color, brNone);
Artists = new Menu<std::string>(0, MainStartY, itsLeftColWidth, MainHeight, Config.titles_visibility ? tagTypeToString(Config.media_lib_primary_tag) + "s" : "", Config.main_color, brNone);
Artists->HighlightColor(Config.active_column_color);
Artists->CyclicScrolling(Config.use_cyclic_scrolling);
Artists->CenteredCursor(Config.centered_cursor);
@@ -162,7 +163,7 @@ void MediaLibrary::SwitchTo()
NextColumn();
if (Config.titles_visibility)
{
std::string item_type = IntoStr(Config.media_lib_primary_tag);
std::string item_type = tagTypeToString(Config.media_lib_primary_tag);
lowercase(item_type);
Albums->SetTitle("Albums (sorted by " + item_type + ")");
}
@@ -635,7 +636,7 @@ void MediaLibrary::LocateSong(const MPD::Song &s)
}
if (primary_tag.empty())
{
std::string item_type = IntoStr(Config.media_lib_primary_tag);
std::string item_type = tagTypeToString(Config.media_lib_primary_tag);
lowercase(item_type);
ShowMessage("Can't use this function because the song has no %s tag set", item_type.c_str());
return;
@@ -726,7 +727,7 @@ void MediaLibrary::AddToPlaylist(bool add_n_play)
if ((!Artists->Empty() && w == Artists)
|| (w == Albums && Albums->Current().Date == AllTracksMarker))
{
std::string tag_type = IntoStr(Config.media_lib_primary_tag);
std::string tag_type = tagTypeToString(Config.media_lib_primary_tag);
lowercase(tag_type);
ShowMessage("Songs with %s = \"%s\" added", tag_type.c_str(), Artists->Current().c_str());
}
@@ -790,9 +791,9 @@ bool MediaLibrary::SearchConstraintsSorting::operator()(const SearchConstraints
bool MediaLibrary::SortSongsByTrack(const MPD::Song &a, const MPD::Song &b)
{
if (a.getDisc() == b.getDisc())
return StrToInt(a.getTrack()) < StrToInt(b.getTrack());
return stringToInt(a.getTrack()) < stringToInt(b.getTrack());
else
return StrToInt(a.getDisc()) < StrToInt(b.getDisc());
return stringToInt(a.getDisc()) < stringToInt(b.getDisc());
}
bool MediaLibrary::SortAllTracks(const MPD::Song &a, const MPD::Song &b)

View File

@@ -26,6 +26,7 @@
# include <sys/stat.h>
#endif // WIN32
#include <cstdlib>
#include <cstring>
#include <string>
#include <fstream>
#include <iostream>
@@ -46,6 +47,7 @@
#include "settings.h"
#include "tag_editor.h"
#include "visualizer.h"
#include "utility/type_conversions.h"
#ifdef HAVE_LANGINFO_H
# include <langinfo.h>
@@ -56,12 +58,36 @@ KeyConfiguration Keys;
namespace
{
Border IntoBorder(const std::string &color)
NCurses::Color stringToColor(const std::string &color)
{
return Border(IntoColor(color));
NCurses::Color result = NCurses::clDefault;
if (color == "black")
result = NCurses::clBlack;
else if (color == "red")
result = NCurses::clRed;
else if (color == "green")
result = NCurses::clGreen;
else if (color == "yellow")
result = NCurses::clYellow;
else if (color == "blue")
result = NCurses::clBlue;
else if (color == "magenta")
result = NCurses::clMagenta;
else if (color == "cyan")
result = NCurses::clCyan;
else if (color == "white")
result = NCurses::clWhite;
return result;
}
BasicScreen *IntoScreen(int n)
Border stringToBorder(const std::string &border)
{
return Border(stringToColor(border));
}
BasicScreen *intToScreen(int n)
{
switch (n)
{
@@ -488,33 +514,33 @@ void Configuration::Read()
}
else if (name == "mpd_port")
{
if (StrToInt(v))
mpd_port = StrToInt(v);
if (stringToInt(v))
mpd_port = stringToInt(v);
}
else if (name == "mpd_connection_timeout")
{
if (StrToInt(v))
mpd_connection_timeout = StrToInt(v);
if (stringToInt(v))
mpd_connection_timeout = stringToInt(v);
}
else if (name == "mpd_crossfade_time")
{
if (StrToInt(v) > 0)
crossfade_time = StrToInt(v);
if (stringToInt(v) > 0)
crossfade_time = stringToInt(v);
}
else if (name == "seek_time")
{
if (StrToInt(v) > 0)
seek_time = StrToInt(v);
if (stringToInt(v) > 0)
seek_time = stringToInt(v);
}
else if (name == "playlist_disable_highlight_delay")
{
if (StrToInt(v) >= 0)
playlist_disable_highlight_delay = StrToInt(v);
if (stringToInt(v) >= 0)
playlist_disable_highlight_delay = stringToInt(v);
}
else if (name == "message_delay_time")
{
if (StrToInt(v) > 0)
message_delay_time = StrToInt(v);
if (stringToInt(v) > 0)
message_delay_time = stringToInt(v);
}
else if (name == "song_list_format")
{
@@ -689,12 +715,12 @@ void Configuration::Read()
else if (name == "color1")
{
if (!v.empty())
color1 = IntoColor(v);
color1 = stringToColor(v);
}
else if (name == "color2")
{
if (!v.empty())
color2 = IntoColor(v);
color2 = stringToColor(v);
}
else if (name == "mpd_communication_mode")
{
@@ -768,7 +794,7 @@ void Configuration::Read()
++it;
if (it == v.end())
break;
if (BasicScreen *screen = IntoScreen(atoi(&*it)))
if (BasicScreen *screen = intToScreen(atoi(&*it)))
screens_seq.push_back(screen);
while (it != v.end() && isdigit(*it))
++it;
@@ -779,7 +805,7 @@ void Configuration::Read()
}
else if (name == "startup_screen")
{
startup_screen = IntoScreen(atoi(v.c_str()));
startup_screen = intToScreen(atoi(v.c_str()));
if (!startup_screen)
startup_screen = myPlaylist;
}
@@ -932,20 +958,20 @@ void Configuration::Read()
else if (name == "lines_scrolled")
{
if (!v.empty())
lines_scrolled = StrToInt(v);
lines_scrolled = stringToInt(v);
}
else if (name == "search_engine_default_search_mode")
{
if (!v.empty())
{
unsigned mode = StrToInt(v);
unsigned mode = stringToInt(v);
if (--mode < 3)
search_engine_default_search_mode = mode;
}
}
else if (name == "visualizer_sync_interval")
{
unsigned interval = StrToInt(v);
unsigned interval = stringToInt(v);
if (interval)
visualizer_sync_interval = interval;
}
@@ -960,7 +986,7 @@ void Configuration::Read()
}
else if (name == "locked_screen_width_part")
{
int part = StrToInt(v);
int part = stringToInt(v);
if (part)
locked_screen_width_part = part/100.0;
}
@@ -990,82 +1016,82 @@ void Configuration::Read()
else if (name == "empty_tag_color")
{
if (!v.empty())
empty_tags_color = IntoColor(v);
empty_tags_color = stringToColor(v);
}
else if (name == "header_window_color")
{
if (!v.empty())
header_color = IntoColor(v);
header_color = stringToColor(v);
}
else if (name == "volume_color")
{
if (!v.empty())
volume_color = IntoColor(v);
volume_color = stringToColor(v);
}
else if (name == "state_line_color")
{
if (!v.empty())
state_line_color = IntoColor(v);
state_line_color = stringToColor(v);
}
else if (name == "state_flags_color")
{
if (!v.empty())
state_flags_color = IntoColor(v);
state_flags_color = stringToColor(v);
}
else if (name == "main_window_color")
{
if (!v.empty())
main_color = IntoColor(v);
main_color = stringToColor(v);
}
else if (name == "main_window_highlight_color")
{
if (!v.empty())
main_highlight_color = IntoColor(v);
main_highlight_color = stringToColor(v);
}
else if (name == "progressbar_color")
{
if (!v.empty())
progressbar_color = IntoColor(v);
progressbar_color = stringToColor(v);
}
else if (name == "progressbar_elapsed_color")
{
if (!v.empty())
progressbar_elapsed_color = IntoColor(v);
progressbar_elapsed_color = stringToColor(v);
}
else if (name == "statusbar_color")
{
if (!v.empty())
statusbar_color = IntoColor(v);
statusbar_color = stringToColor(v);
}
else if (name == "alternative_ui_separator_color")
{
if (!v.empty())
alternative_ui_separator_color = IntoColor(v);
alternative_ui_separator_color = stringToColor(v);
}
else if (name == "active_column_color")
{
if (!v.empty())
active_column_color = IntoColor(v);
active_column_color = stringToColor(v);
}
else if (name == "visualizer_color")
{
if (!v.empty())
visualizer_color = IntoColor(v);
visualizer_color = stringToColor(v);
}
else if (name == "window_border_color")
{
if (!v.empty())
window_border = IntoBorder(v);
window_border = stringToBorder(v);
}
else if (name == "active_window_border")
{
if (!v.empty())
active_window_border = IntoBorder(v);
active_window_border = stringToBorder(v);
}
else if (name == "media_library_left_column")
{
if (!v.empty())
media_lib_primary_tag = IntoTagItem(v[0]);
media_lib_primary_tag = charToTagType(v[0]);
}
else
std::cout << "Unknown option: " << name << ", ignoring.\n";
@@ -1082,7 +1108,7 @@ void Configuration::GenerateColumns()
while (!(width = getEnclosedString(song_list_columns_format, '(', ')', &pos)).empty())
{
Column col;
col.color = IntoColor(getEnclosedString(song_list_columns_format, '[', ']', &pos));
col.color = stringToColor(getEnclosedString(song_list_columns_format, '[', ']', &pos));
std::string tag_type = getEnclosedString(song_list_columns_format, '{', '}', &pos);
col.fixed = *width.rbegin() == 'f';
@@ -1121,7 +1147,7 @@ void Configuration::GenerateColumns()
else // empty column
col.display_empty_tag = 0;
col.width = StrToInt(width);
col.width = stringToInt(width);
columns.push_back(col);
}

View File

@@ -24,7 +24,9 @@
#include <memory>
#include "song.h"
#include "conv.h"
#include "utility/numeric_conversions.h"
#include "utility/type_conversions.h"
#include "window.h"
namespace {//
@@ -282,12 +284,10 @@ std::string Song::ShowTime(unsigned length)
length -= minutes*60;
int seconds = length;
char buf[32];
if (hours > 0)
snprintf(buf, sizeof(buf), "%d:%02d:%02d", hours, minutes, seconds);
return print<32, std::string>::apply("%d:%02d:%02d", hours, minutes, seconds);
else
snprintf(buf, sizeof(buf), "%d:%02d", minutes, seconds);
return buf;
return print<32, std::string>::apply("%d:%02d", minutes, seconds);
}
bool MPD::Song::isFormatOk(const std::string &type, const std::string &fmt)
@@ -310,7 +310,7 @@ bool MPD::Song::isFormatOk(const std::string &type, const std::string &fmt)
{
if (isdigit(fmt[++i]))
while (isdigit(fmt[++i])) { }
if (!toGetFunction(fmt[i]))
if (!charToGetFunction(fmt[i]))
{
std::cerr << type << ": invalid character at position " << unsignedLongIntTo<std::string>::apply(i+1) << ": '" << fmt[i] << "'\n";
return false;
@@ -353,7 +353,7 @@ std::string Song::ParseFormat(std::string::const_iterator &it, const std::string
get = 0;
}
else
get = toGetFunction(*it);
get = charToGetFunction(*it);
if (get)
{
@@ -368,9 +368,9 @@ std::string Song::ParseFormat(std::string::const_iterator &it, const std::string
{
if (delimiter)
{
const std::basic_string<my_char_t> &s = TO_WSTRING(tag);
/*const std::basic_string<my_char_t> &s = TO_WSTRING(tag);
if (NCurses::Window::Length(s) > delimiter)
tag = Shorten(s, delimiter);
tag = Shorten(s, delimiter);*/
}
has_some_tags = 1;
result += tag;

View File

@@ -22,7 +22,7 @@
#define _SONG_INFO_H
#include "screen.h"
#include "song.h"
#include "mutable_song.h"
class SongInfo : public Screen<Scrollpad>
{

View File

@@ -21,9 +21,8 @@
#ifndef _STRBUFFER_H
#define _STRBUFFER_H
#include "numeric_conversions.h"
#include "window.h"
#include "utility/string.h"
#include "utility/numeric_conversions.h"
#include <list>

View File

@@ -625,7 +625,7 @@ void TagEditor::EnterPressed()
if (!WriteTags(**it))
{
const char msg[] = "Error while writing tags in \"%s\"";
ShowMessage(msg, Shorten(TO_WSTRING((*it)->getURI()), COLS-static_strlen(msg)).c_str());
ShowMessage(msg, Shorten(TO_WSTRING((*it)->getURI()), COLS-const_strlen(msg)).c_str());
success = 0;
break;
}
@@ -1026,8 +1026,8 @@ bool TagEditor::WriteTags(MPD::MutableSong &s)
f.tag()->setTitle(ToWString(s.getTitle()));
f.tag()->setArtist(ToWString(s.getArtist()));
f.tag()->setAlbum(ToWString(s.getAlbum()));
f.tag()->setYear(StrToInt(s.getDate()));
f.tag()->setTrack(StrToInt(s.getTrack()));
f.tag()->setYear(stringToInt(s.getDate()));
f.tag()->setTrack(stringToInt(s.getTrack()));
f.tag()->setGenre(ToWString(s.getGenre()));
f.tag()->setComment(ToWString(s.getComment()));
if (TagLib::MPEG::File *mp3_file = dynamic_cast<TagLib::MPEG::File *>(f.file()))
@@ -1219,7 +1219,7 @@ MPD::MutableSong::SetFunction TagEditor::IntoSetFunction(char c)
std::string TagEditor::GenerateFilename(const MPD::MutableSong &s, const std::string &pattern)
{
std::string result = s.toString(pattern);
EscapeUnallowedChars(result);
removeInvalidCharsFromFilename(result);
return result;
}

View File

@@ -33,6 +33,7 @@
#include "tag.h"
#include "mpdpp.h"
#include "mutable_song.h"
#include "screen.h"
class TagEditor : public Screen<Window>

View File

@@ -28,6 +28,7 @@
// taglib includes
#include "tfile.h"
#include "mutable_song.h"
#include "screen.h"
class TinyTagEditor : public Screen< Menu<Buffer> >

View File

@@ -18,75 +18,58 @@
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#include <cstdio>
#include <cwchar>
#include <string>
#include "string.h"
#ifndef _NUMERIC_CONVERSIONS_H
#define _NUMERIC_CONVERSIONS_H
#ifndef _UTILITY_NUMERIC_CONVERSIONS_H
#define _UTILITY_NUMERIC_CONVERSIONS_H
template <typename R> struct intTo { };
template <> struct intTo<std::string> {
static std::string apply(int n) {
char buf[32];
snprintf(buf, sizeof(buf), "%d", n);
return buf;
return print<32, std::string>::apply("%d", n);
}
};
template <> struct intTo<std::wstring> {
static std::wstring apply(int n) {
wchar_t buf[32];
swprintf(buf, sizeof(buf)/sizeof(wchar_t), L"%d", n);
return buf;
return print<32, std::wstring>::apply(L"%d", n);
}
};
template <typename R> struct longIntTo { };
template <> struct longIntTo<std::string> {
static std::string apply(long int n) {
char buf[32];
snprintf(buf, sizeof(buf), "%ld", n);
return buf;
return print<32, std::string>::apply("%ld", n);
}
};
template <> struct longIntTo<std::wstring> {
static std::wstring apply(long int n) {
wchar_t buf[32];
swprintf(buf, sizeof(buf)/sizeof(wchar_t), L"%ld", n);
return buf;
return print<32, std::wstring>::apply(L"%ld", n);
}
};
template <typename R> struct unsignedIntTo { };
template <> struct unsignedIntTo<std::string> {
static std::string apply(unsigned int n) {
char buf[32];
snprintf(buf, sizeof(buf), "%u", n);
return buf;
return print<32, std::string>::apply("%u", n);
}
};
template <> struct unsignedIntTo<std::wstring> {
static std::wstring apply(unsigned int n) {
wchar_t buf[32];
swprintf(buf, sizeof(buf)/sizeof(wchar_t), L"%u", n);
return buf;
return print<32, std::wstring>::apply(L"%u", n);
}
};
template <typename R> struct unsignedLongIntTo { };
template <> struct unsignedLongIntTo<std::string> {
static std::string apply(unsigned long int n) {
char buf[32];
snprintf(buf, sizeof(buf), "%lu", n);
return buf;
return print<32, std::string>::apply("%lu", n);
}
};
template <> struct unsignedLongIntTo<std::wstring> {
static std::wstring apply(unsigned long int n) {
wchar_t buf[32];
swprintf(buf, sizeof(buf)/sizeof(wchar_t), L"%lu", n);
return buf;
return print<32, std::wstring>::apply(L"%lu", n);
}
};
#endif // _NUMERIC_CONVERSIONS_H
#endif // _UTILITY_NUMERIC_CONVERSIONS_H

View File

@@ -23,6 +23,52 @@
#include <algorithm>
#include "utility/string.h"
int stringToInt(const std::string &s)
{
return atoi(s.c_str());
}
long stringToLongInt(const std::string &s)
{
return atol(s.c_str());
}
bool isInteger(const char *s)
{
assert(s);
if (*s == '\0')
return false;
for (const char *it = s; *it != '\0'; ++it)
if (!isdigit(*it) && (it != s || *it != '-'))
return false;
return true;
}
std::string ToString(const std::wstring &ws)
{
std::string result;
char s[MB_CUR_MAX];
for (size_t i = 0; i < ws.length(); ++i)
{
int n = wcrtomb(s, ws[i], 0);
if (n > 0)
result.append(s, n);
}
return result;
}
std::wstring ToWString(const std::string &s)
{
std::wstring result;
wchar_t *ws = new wchar_t[s.length()];
const char *c_s = s.c_str();
int n = mbsrtowcs(ws, &c_s, s.length(), 0);
if (n > 0)
result.append(ws, n);
delete [] ws;
return result;
}
std::vector<std::string> split(const std::string &s, const std::string &delimiter)
{
if (delimiter.empty())
@@ -134,13 +180,18 @@ std::string getEnclosedString(const std::string &s, char a, char b, size_t *pos)
return result;
}
bool isInteger(const char *s)
void removeInvalidCharsFromFilename(std::string &filename)
{
assert(s);
if (*s == '\0')
return false;
for (const char *it = s; *it != '\0'; ++it)
if (!isdigit(*it) && (it != s || *it != '-'))
return false;
return true;
const char *unallowed_chars = "\"*/:<>?\\|";
for (const char *c = unallowed_chars; *c; ++c)
{
for (size_t i = 0; i < filename.length(); ++i)
{
if (filename[i] == *c)
{
filename.erase(filename.begin()+i);
--i;
}
}
}
}

View File

@@ -21,8 +21,43 @@
#ifndef _UTILITY_STRING
#define _UTILITY_STRING
#include <cstdarg>
#include <string>
#include <vector>
#include "gcc.h"
template <size_t N> size_t const_strlen(const char (&)[N]) {
return N-1;
}
template <size_t N, typename T> struct print { };
template <size_t N> struct print<N, std::string> {
static std::string apply(const char *format, ...) GNUC_PRINTF(1, 2) {
char buf[N];
va_list args;
va_start(args, format);
vsnprintf(buf, sizeof(buf)/sizeof(char), format, args);
va_end(args);
return buf;
}
};
template <size_t N> struct print<N, std::wstring> {
static std::wstring apply(const wchar_t *format, ...) {
wchar_t buf[N];
va_list args;
va_start(args, format);
vswprintf(buf, sizeof(buf)/sizeof(wchar_t), format, args);
va_end(args);
return buf;
}
};
int stringToInt(const std::string &s);
long stringToLongInt(const std::string &s);
bool isInteger(const char *s);
std::string ToString(const std::wstring &ws);
std::wstring ToWString(const std::string &s);
std::vector<std::string> split(const std::string &s, const std::string &delimiter);
void replace(std::string &s, const std::string &from, const std::string &to);
@@ -38,6 +73,6 @@ std::string getSharedDirectory(const std::string &dir1, const std::string &dir2)
std::string getEnclosedString(const std::string &s, char a, char b, size_t *pos);
bool isInteger(const char *s);
void removeInvalidCharsFromFilename(std::string &filename);
#endif // _UTILITY_STRING

View File

@@ -0,0 +1,157 @@
/***************************************************************************
* Copyright (C) 2008-2012 by Andrzej Rybczak *
* electricityispower@gmail.com *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#include <cassert>
#include "utility/type_conversions.h"
std::string tagTypeToString(mpd_tag_type tag)
{
switch (tag)
{
case MPD_TAG_ARTIST:
return "Artist";
case MPD_TAG_ALBUM:
return "Album";
case MPD_TAG_ALBUM_ARTIST:
return "Album Artist";
case MPD_TAG_TITLE:
return "Title";
case MPD_TAG_TRACK:
return "Track";
case MPD_TAG_GENRE:
return "Genre";
case MPD_TAG_DATE:
return "Date";
case MPD_TAG_COMPOSER:
return "Composer";
case MPD_TAG_PERFORMER:
return "Performer";
case MPD_TAG_COMMENT:
return "Comment";
case MPD_TAG_DISC:
return "Disc";
default:
return "";
}
}
MPD::MutableSong::SetFunction tagTypeToSetFunction(mpd_tag_type tag)
{
switch (tag)
{
case MPD_TAG_ARTIST:
return &MPD::MutableSong::setArtist;
case MPD_TAG_ALBUM:
return &MPD::MutableSong::setAlbum;
case MPD_TAG_ALBUM_ARTIST:
return &MPD::MutableSong::setAlbumArtist;
case MPD_TAG_TITLE:
return &MPD::MutableSong::setTitle;
case MPD_TAG_TRACK:
return &MPD::MutableSong::setTrack;
case MPD_TAG_GENRE:
return &MPD::MutableSong::setGenre;
case MPD_TAG_DATE:
return &MPD::MutableSong::setDate;
case MPD_TAG_COMPOSER:
return &MPD::MutableSong::setComposer;
case MPD_TAG_PERFORMER:
return &MPD::MutableSong::setPerformer;
case MPD_TAG_COMMENT:
return &MPD::MutableSong::setComment;
case MPD_TAG_DISC:
return &MPD::MutableSong::setDisc;
default:
return 0;
}
}
mpd_tag_type charToTagType(char c)
{
switch (c)
{
case 'a':
return MPD_TAG_ARTIST;
case 'A':
return MPD_TAG_ALBUM_ARTIST;
case 't':
return MPD_TAG_TITLE;
case 'b':
return MPD_TAG_ALBUM;
case 'y':
return MPD_TAG_DATE;
case 'n':
return MPD_TAG_TRACK;
case 'g':
return MPD_TAG_GENRE;
case 'c':
return MPD_TAG_COMPOSER;
case 'p':
return MPD_TAG_PERFORMER;
case 'd':
return MPD_TAG_DISC;
case 'C':
return MPD_TAG_COMMENT;
default:
assert(false);
return MPD_TAG_ARTIST;
}
}
MPD::Song::GetFunction charToGetFunction(char c)
{
switch (c)
{
case 'l':
return &MPD::Song::getLength;
case 'D':
return &MPD::Song::getDirectory;
case 'f':
return &MPD::Song::getName;
case 'a':
return &MPD::Song::getArtist;
case 'A':
return &MPD::Song::getAlbumArtist;
case 't':
return &MPD::Song::getTitle;
case 'b':
return &MPD::Song::getAlbum;
case 'y':
return &MPD::Song::getDate;
case 'n':
return &MPD::Song::getTrackNumber;
case 'N':
return &MPD::Song::getTrack;
case 'g':
return &MPD::Song::getGenre;
case 'c':
return &MPD::Song::getComposer;
case 'p':
return &MPD::Song::getPerformer;
case 'd':
return &MPD::Song::getDisc;
case 'C':
return &MPD::Song::getComment;
case 'P':
return &MPD::Song::getPriority;
default:
return 0;
}
}

View File

@@ -18,43 +18,15 @@
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#ifndef _CONV_H
#define _CONV_H
#ifndef _UTILITY_TYPE_CONVERSIONS
#define _UTILITY_TYPE_CONVERSIONS
#include <cstring>
#include <string>
#include "numeric_conversions.h"
#include "actions.h"
#include "window.h"
#include "mutable_song.h"
#include "song.h"
template <size_t N> inline size_t static_strlen(const char (&)[N])
{
return N-1;
}
std::string tagTypeToString(mpd_tag_type tag);
MPD::MutableSong::SetFunction tagTypeToSetFunction(mpd_tag_type tag);
int StrToInt(const std::string &);
long StrToLong(const std::string &);
std::string IntoStr(mpd_tag_type);
std::string IntoStr(NCurses::Color);
std::string IntoStr(const Action::Key &key, bool *print_backspace = 0);
NCurses::Color IntoColor(const std::string &);
mpd_tag_type IntoTagItem(char);
MPD::Song::GetFunction toGetFunction(char c);
#ifdef HAVE_TAGLIB_H
MPD::MutableSong::SetFunction IntoSetFunction(mpd_tag_type);
#endif // HAVE_TAGLIB_H
std::string Shorten(const std::basic_string<my_char_t> &s, size_t max_length);
void EscapeUnallowedChars(std::string &);
#endif
mpd_tag_type charToTagType(char c);
MPD::Song::GetFunction charToGetFunction(char c);
#endif // _UTILITY_TYPE_CONVERSIONS

View File

@@ -29,6 +29,7 @@
#endif
#include "error.h"
#include "utility/string.h"
#include "window.h"
using namespace NCurses;
@@ -923,31 +924,6 @@ Window &Window::operator<<(size_t s)
return *this;
}
std::string ToString(const std::wstring &ws)
{
std::string result;
char s[MB_CUR_MAX];
for (size_t i = 0; i < ws.length(); ++i)
{
int n = wcrtomb(s, ws[i], 0);
if (n > 0)
result.append(s, n);
}
return result;
}
std::wstring ToWString(const std::string &s)
{
std::wstring result;
wchar_t *ws = new wchar_t[s.length()];
const char *c_s = s.c_str();
int n = mbsrtowcs(ws, &c_s, s.length(), 0);
if (n > 0)
result.append(ws, n);
delete [] ws;
return result;
}
size_t Window::Length(const std::wstring &ws)
{
# ifdef WIN32

View File

@@ -117,18 +117,6 @@
# define wcwidth(x) int(!iscntrl(x))
#endif
/// Converts wide string to narrow string
/// @param ws wide string
/// @return narrow string
///
std::string ToString(const std::wstring &ws);
/// Converts narrow string to wide string
/// @param s narrow string
/// @return wide string
///
std::wstring ToWString(const std::string &s);
/// NCurses namespace provides set of easy-to-use
/// wrappers over original curses library
///