File indexing completed on 2024-05-05 05:40:40

0001 /***************************************************************************
0002  *  Copyright (C) 2021 by Renaud Guezennec                               *
0003  *   http://www.rolisteam.org/contact                                      *
0004  *                                                                         *
0005  *   This software is free software; you can redistribute it and/or modify *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 2 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  *                                                                         *
0010  *   This program is distributed in the hope that it will be useful,       *
0011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0013  *   GNU General Public License for more details.                          *
0014  *                                                                         *
0015  *   You should have received a copy of the GNU General Public License     *
0016  *   along with this program; if not, write to the                         *
0017  *   Free Software Foundation, Inc.,                                       *
0018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
0019  ***************************************************************************/
0020 #include "worker/utilshelper.h"
0021 
0022 #include <QBrush>
0023 #include <QImageReader>
0024 #include <QPainter>
0025 #include <QtConcurrent>
0026 
0027 namespace helper
0028 {
0029 namespace utils
0030 {
0031 QString allSupportedImageFormatFilter()
0032 {
0033     auto allFormats= QImageReader::supportedImageFormats();
0034 
0035     QStringList list;
0036     std::transform(std::begin(allFormats), std::end(allFormats), std::back_inserter(list),
0037                    [](const QByteArray& array) { return QString("*.%1").arg(QString::fromLocal8Bit(array)); });
0038 
0039     return list.join(" ");
0040 }
0041 
0042 QRectF computerBiggerRectInside(const QRect& rect, qreal ratio)
0043 {
0044     QRectF res(rect);
0045     auto const r= ratio;
0046 
0047     auto const reversed= 1 / r;
0048 
0049     auto future_W= res.height() * r;
0050     auto const future_H= res.width() * reversed;
0051 
0052     if(future_W < future_H && future_W <= rect.width())
0053     {
0054         res.setWidth(future_W);
0055     }
0056     else
0057     {
0058         if(future_H <= res.height())
0059             res.setHeight(future_H);
0060         else
0061         {
0062             res.setWidth(future_W);
0063         }
0064     }
0065 
0066     return res;
0067 }
0068 
0069 QPixmap roundCornerImage(const QPixmap& source, int size, int radius)
0070 {
0071     QPixmap img(size, size);
0072     img.fill(Qt::transparent);
0073     QPainter painter(&img);
0074     QBrush brush;
0075     brush.setTextureImage(source.toImage().scaled(size, size));
0076     painter.setBrush(brush);
0077     painter.drawRoundedRect(0, 0, size, size, radius, radius);
0078     return img;
0079 }
0080 
0081 bool isSquareImage(const QByteArray& array)
0082 {
0083     auto img= QImage::fromData(array);
0084     return !img.isNull() && img.width() == img.height();
0085 }
0086 
0087 bool hasValidCharacter(const std::vector<connection::CharacterData>& characters, bool isGameMaster)
0088 {
0089     return isGameMaster ? true :
0090                           std::any_of(std::begin(characters), std::end(characters),
0091                                       [](const connection::CharacterData& data)
0092                                       {
0093                                           auto s= isSquareImage(data.m_avatarData);
0094                                           return !data.m_name.isEmpty() && s;
0095                                       });
0096 }
0097 
0098 QStringList extentionPerType(Core::ContentType type, bool save, bool wildcard)
0099 {
0100     QStringList exts;
0101     switch(type)
0102     {
0103     case Core::ContentType::CHARACTERSHEET:
0104         exts= QStringList{Core::extentions::EXT_SHEET}; // QObject::tr("Character Sheets files  (%1)").arg("*.rcs");
0105         break;
0106     case Core::ContentType::PICTURE:
0107         exts= QStringList{Core::extentions::EXT_IMG_BMP, Core::extentions::EXT_IMG_JPG, Core::extentions::EXT_IMG_JPEG,
0108                           Core::extentions::EXT_IMG_PNG, Core::extentions::EXT_IMG_SVG, Core::extentions::EXT_IMG_GIF};
0109         break;
0110     case Core::ContentType::NOTES:
0111         exts= save ? QStringList{Core::extentions::EXT_OPEN_DOCUMENT} :
0112                      QStringList{Core::extentions::EXT_OPEN_DOCUMENT, Core::extentions::EXT_HTM,
0113                                  Core::extentions::EXT_HTML,          Core::extentions::EXT_XHTML,
0114                                  Core::extentions::EXT_MARKDOWN,      Core::extentions::EXT_TEXT};
0115 
0116         break;
0117     case Core::ContentType::SHAREDNOTE:
0118         exts= save ? QStringList{Core::extentions::EXT_SHAREDNOTE} :
0119                      QStringList{Core::extentions::EXT_SHAREDNOTE, Core::extentions::EXT_HTM,
0120                                  Core::extentions::EXT_HTML,       Core::extentions::EXT_XHTML,
0121                                  Core::extentions::EXT_MARKDOWN,   Core::extentions::EXT_TEXT};
0122 
0123         break;
0124     case Core::ContentType::WEBVIEW:
0125         exts= save ? QStringList{Core::extentions::EXT_WEBVIEW} :
0126                      QStringList{
0127                          Core::extentions::EXT_WEBVIEW,
0128                          Core::extentions::EXT_HTM,
0129                          Core::extentions::EXT_HTML,
0130                          Core::extentions::EXT_XHTML,
0131                      };
0132         break;
0133     case Core::ContentType::PDF:
0134         exts= QStringList{Core::extentions::EXT_PDF}; // QObject::tr("Pdf File (%1)").arg("*.pdf");
0135         break;
0136     case Core::ContentType::VECTORIALMAP:
0137         exts= QStringList{Core::extentions::EXT_MAP}; // QObject::tr("Vectorial Map (%1)").arg("*.vmap");
0138         break;
0139     case Core::ContentType::MINDMAP:
0140         exts= QStringList{Core::extentions::EXT_MINDMAP}; // QObject::tr("Mindmap (%1)").arg("*.rmap");
0141         break;
0142     default:
0143         break;
0144     }
0145 
0146     QStringList res;
0147     if(wildcard)
0148     {
0149         res.reserve(exts.size());
0150         std::transform(std::begin(exts), std::end(exts), std::back_inserter(res),
0151                        [](const QString& ext) { return QString("*%1").arg(ext); });
0152     }
0153     else
0154     {
0155         res= exts;
0156     }
0157     return res;
0158 }
0159 
0160 QString filterForType(Core::ContentType type, bool save)
0161 {
0162     QString filterType;
0163     auto list= extentionPerType(type, save, true).join(' ');
0164     switch(type)
0165     {
0166     case Core::ContentType::CHARACTERSHEET:
0167         filterType= QObject::tr("Character Sheets files  (%1)").arg(list);
0168         break;
0169     case Core::ContentType::PICTURE:
0170         filterType= QObject::tr("Supported Image formats (%1)").arg(list);
0171         break;
0172     case Core::ContentType::NOTES:
0173         filterType= QObject::tr("Supported Text Files (%1)").arg(list);
0174         break;
0175     case Core::ContentType::SHAREDNOTE:
0176         filterType= QObject::tr("Supported Shared Note formats (%1)").arg(list);
0177         break;
0178     case Core::ContentType::WEBVIEW:
0179         filterType= QObject::tr("Supported WebPage (%1)").arg(list);
0180         break;
0181     case Core::ContentType::PDF:
0182         filterType= QObject::tr("Pdf File (%1)").arg(list);
0183         break;
0184     case Core::ContentType::VECTORIALMAP:
0185         filterType= QObject::tr("Vectorial Map (%1)").arg(list);
0186         break;
0187     case Core::ContentType::MINDMAP:
0188         filterType= QObject::tr("Mindmap (%1)").arg(list);
0189         break;
0190     default:
0191         filterType= QString();
0192         break;
0193     }
0194     return filterType;
0195 }
0196 
0197 QString typeToString(Core::ContentType type)
0198 {
0199     // WARNING Test with different langs
0200     QHash<Core::ContentType, QString> names;
0201 
0202     names.insert(Core::ContentType::VECTORIALMAP, QObject::tr("Vectorial Map"));
0203     names.insert(Core::ContentType::PICTURE, QObject::tr("Picture"));
0204     names.insert(Core::ContentType::NOTES, QObject::tr("Minutes"));
0205     names.insert(Core::ContentType::CHARACTERSHEET, QObject::tr("Character Sheet"));
0206     names.insert(Core::ContentType::MINDMAP, QObject::tr("Mindmap"));
0207     names.insert(Core::ContentType::SHAREDNOTE, QObject::tr("Shared Notes"));
0208     names.insert(Core::ContentType::PDF, QObject::tr("Pdf"));
0209     names.insert(Core::ContentType::WEBVIEW, QObject::tr("Webview"));
0210 
0211     return names.value(type);
0212 }
0213 
0214 Core::ContentType mediaTypeToContentType(Core::MediaType type)
0215 {
0216     auto res= Core::ContentType::UNKNOWN;
0217 
0218     switch(type)
0219     {
0220     case Core::MediaType::Unknown:
0221     case Core::MediaType::TokenFile:
0222     case Core::MediaType::PlayListFile:
0223     case Core::MediaType::AudioFile:
0224         res= Core::ContentType::UNKNOWN;
0225         break;
0226     case Core::MediaType::ImageFile:
0227         res= Core::ContentType::PICTURE;
0228         break;
0229     case Core::MediaType::MapFile:
0230         res= Core::ContentType::VECTORIALMAP;
0231         break;
0232     case Core::MediaType::TextFile:
0233         res= Core::ContentType::NOTES;
0234         break;
0235     case Core::MediaType::CharacterSheetFile:
0236         res= Core::ContentType::CHARACTERSHEET;
0237         break;
0238     case Core::MediaType::PdfFile:
0239         res= Core::ContentType::PDF;
0240         break;
0241     case Core::MediaType::WebpageFile:
0242         res= Core::ContentType::WEBVIEW;
0243         break;
0244     case Core::MediaType::MindmapFile:
0245         res= Core::ContentType::MINDMAP;
0246         break;
0247     }
0248 
0249     return res;
0250 }
0251 
0252 QString typeToIconPath(Core::ContentType type)
0253 {
0254     auto hash= QHash<Core::ContentType, QString>({
0255         {Core::ContentType::VECTORIALMAP, "vmap"},
0256         {Core::ContentType::PICTURE, "photo"},
0257         //{Core::ContentType::ONLINEPICTURE, "photo"},
0258         {Core::ContentType::NOTES, "notes"},
0259         {Core::ContentType::CHARACTERSHEET, "treeview"},
0260         {Core::ContentType::SHAREDNOTE, "sharedEditor"},
0261         {Core::ContentType::WEBVIEW, "webPage"},
0262         {Core::ContentType::PDF, "pdfLogo"},
0263     });
0264     return hash.value(type);
0265 }
0266 
0267 Core::ContentType extensionToContentType(const QString& filename)
0268 {
0269     QSet<Core::ContentType> types{Core::ContentType::VECTORIALMAP, Core::ContentType::PICTURE,
0270                                   Core::ContentType::NOTES,        Core::ContentType::MINDMAP,
0271                                   Core::ContentType::SHAREDNOTE,   Core::ContentType::PDF,
0272                                   Core::ContentType::WEBVIEW,      Core::ContentType::CHARACTERSHEET};
0273     for(auto type : types)
0274     {
0275         auto list= extentionPerType(type, false);
0276         for(const auto& ext : list)
0277         {
0278             if(filename.endsWith(ext,Qt::CaseInsensitive))
0279                 return type;
0280         }
0281     }
0282     return Core::ContentType::UNKNOWN;
0283 }
0284 
0285 } // namespace utils
0286 } // namespace helper