1/*
2 * This file Copyright (C) Mnemosyne LLC
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2
6 * as published by the Free Software Foundation.
7 *
8 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
9 *
10 * $Id: utils.cc 13448 2012-08-19 16:12:20Z jordan $
11 */
12
13#include <iostream>
14
15#include <QApplication>
16#include <QDataStream>
17#include <QFile>
18#include <QFileDialog>
19#include <QFileInfo>
20#include <QInputDialog>
21#include <QObject>
22#include <QSet>
23#include <QStyle>
24
25#include <libtransmission/transmission.h>
26#include <libtransmission/utils.h> // tr_formatter
27
28#include "utils.h"
29
30/***
31****
32***/
33
34QString
35Utils :: remoteFileChooser( QWidget * parent, const QString& title, const QString& myPath, bool dir, bool local )
36{
37    QString path;
38
39    if( local )
40    {
41        if( dir )
42            path = QFileDialog::getExistingDirectory( parent, title, myPath );
43        else
44            path = QFileDialog::getOpenFileName( parent, title, myPath );
45    }
46    else
47        path = QInputDialog::getText( parent, title, tr( "Enter a location:" ), QLineEdit::Normal, myPath, NULL );
48
49    return path;
50}
51
52void
53Utils :: toStderr( const QString& str )
54{
55    std::cerr << qPrintable(str) << std::endl;
56}
57
58const QIcon&
59Utils :: guessMimeIcon( const QString& filename )
60{
61    enum { DISK, DOCUMENT, PICTURE, VIDEO, ARCHIVE, AUDIO, APP, TYPE_COUNT };
62    static QIcon fallback;
63    static QIcon fileIcons[TYPE_COUNT];
64    static QSet<QString> suffixes[TYPE_COUNT];
65
66    if( fileIcons[0].isNull( ) )
67    {
68        fallback = QApplication::style()->standardIcon( QStyle :: SP_FileIcon );
69
70        suffixes[DISK] << QString::fromAscii("iso");
71        fileIcons[DISK]= QIcon::fromTheme( QString::fromAscii("media-optical"), fallback );
72
73        const char * doc_types[] = {
74            "abw", "csv", "doc", "dvi", "htm", "html", "ini", "log", "odp",
75            "ods", "odt", "pdf", "ppt", "ps",  "rtf", "tex", "txt", "xml" };
76        for( int i=0, n=sizeof(doc_types)/sizeof(doc_types[0]); i<n; ++i )
77            suffixes[DOCUMENT] << QString::fromAscii(doc_types[i] );
78        fileIcons[DOCUMENT] = QIcon::fromTheme( QString::fromAscii("text-x-generic"), fallback );
79
80        const char * pic_types[] = {
81            "bmp", "gif", "jpg", "jpeg", "pcx", "png", "psd", "ras", "tga", "tiff" };
82        for( int i=0, n=sizeof(pic_types)/sizeof(pic_types[0]); i<n; ++i )
83            suffixes[PICTURE] << QString::fromAscii(pic_types[i]);
84        fileIcons[PICTURE]  = QIcon::fromTheme( QString::fromAscii("image-x-generic"), fallback );
85
86        const char * vid_types[] = {
87            "3gp", "asf", "avi", "mov", "mpeg", "mpg", "mp4" "mkv", "mov",
88            "ogm", "ogv", "qt", "rm", "wmv" };
89        for( int i=0, n=sizeof(vid_types)/sizeof(vid_types[0]); i<n; ++i )
90            suffixes[VIDEO] << QString::fromAscii(vid_types[i]);
91        fileIcons[VIDEO] = QIcon::fromTheme( QString::fromAscii("video-x-generic"), fallback );
92
93        const char * arc_types[] = {
94            "7z", "ace", "bz2", "cbz", "gz", "gzip", "lzma", "rar", "sft", "tar", "zip" };
95        for( int i=0, n=sizeof(arc_types)/sizeof(arc_types[0]); i<n; ++i )
96            suffixes[VIDEO] << QString::fromAscii(arc_types[i]);
97        fileIcons[ARCHIVE]  = QIcon::fromTheme( QString::fromAscii("package-x-generic"), fallback );
98
99        const char * aud_types[] = {
100            "aac", "ac3", "aiff", "ape", "au", "flac", "m3u", "m4a", "mid", "midi", "mp2",
101            "mp3", "mpc", "nsf", "oga", "ogg", "ra", "ram", "shn", "voc", "wav", "wma" };
102        for( int i=0, n=sizeof(aud_types)/sizeof(aud_types[0]); i<n; ++i )
103            suffixes[AUDIO] << QString::fromAscii(aud_types[i]);
104        fileIcons[AUDIO] = QIcon::fromTheme( QString::fromAscii("audio-x-generic"), fallback );
105
106        const char * exe_types[] = { "bat", "cmd", "com", "exe" };
107        for( int i=0, n=sizeof(exe_types)/sizeof(exe_types[0]); i<n; ++i )
108            suffixes[APP] << QString::fromAscii(exe_types[i]);
109        fileIcons[APP] = QIcon::fromTheme( QString::fromAscii("application-x-executable"), fallback );
110    }
111
112    QString suffix( QFileInfo( filename ).suffix( ).toLower( ) );
113
114    for( int i=0; i<TYPE_COUNT; ++i )
115        if( suffixes[i].contains( suffix ) )
116            return fileIcons[i];
117
118    return fallback;
119}
120
121bool
122Utils :: isValidUtf8 ( const char *s )
123{
124    int n;  // number of bytes in a UTF-8 sequence
125
126    for ( const char *c = s;  *c;  c += n )
127    {
128        if ( (*c & 0x80) == 0x00 )    n = 1;        // ASCII
129        else if ((*c & 0xc0) == 0x80) return false; // not valid
130        else if ((*c & 0xe0) == 0xc0) n = 2;
131        else if ((*c & 0xf0) == 0xe0) n = 3;
132        else if ((*c & 0xf8) == 0xf0) n = 4;
133        else if ((*c & 0xfc) == 0xf8) n = 5;
134        else if ((*c & 0xfe) == 0xfc) n = 6;
135        else return false;
136        for ( int m = 1; m < n; m++ )
137            if ( (c[m] & 0xc0) != 0x80 )
138                return false;
139    }
140    return true;
141}
142