File indexing completed on 2024-04-28 05:38:13

0001 /***************************************************************************
0002  *   Copyright (C) 2009 by Renaud Guezennec                                *
0003  *   http://www.rolisteam.org/contact                   *
0004  *                                                                         *
0005  *   This program 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 "charactersheetwindow.h"
0021 #include "ui_charactersheetwindow.h"
0022 
0023 #include <QAction>
0024 #include <QContextMenuEvent>
0025 #include <QFile>
0026 #include <QFileDialog>
0027 #include <QImage>
0028 #include <QJsonDocument>
0029 #include <QJsonObject>
0030 #include <QMenu>
0031 #include <QPrintDialog>
0032 #include <QPrinter>
0033 #include <QQmlComponent>
0034 #include <QQmlContext>
0035 #include <QQmlProperty>
0036 #include <QQuickItem>
0037 #include <QToolButton>
0038 
0039 #include "charactersheet/charactersheet.h"
0040 #include "charactersheet/charactersheetmodel.h"
0041 #include "charactersheet/csitem.h"
0042 #include "charactersheet_widgets/sheetwidget.h"
0043 #include "controller/view_controller/charactersheetcontroller.h"
0044 #include "data/character.h"
0045 #include "data/player.h"
0046 #include "model/charactermodel.h"
0047 #include "model/playermodel.h"
0048 #include "preferences/preferencesmanager.h"
0049 
0050 CharacterSheetWindow::CharacterSheetWindow(CharacterSheetController* ctrl, QWidget* parent)
0051     : MediaContainer(ctrl, MediaContainer::ContainerType::VMapContainer, parent)
0052     , m_sheetCtrl(ctrl)
0053     , m_ui(new Ui::CharacterSheetWindow)
0054 {
0055     auto wid= new QWidget(this);
0056     m_ui->setupUi(wid);
0057     setWidget(wid);
0058 
0059     setObjectName("CharacterSheetViewer");
0060     connect(m_sheetCtrl, &CharacterSheetController::sheetCreated, this, &CharacterSheetWindow::addTabWithSheetView);
0061     /*connect(&m_model, SIGNAL(characterSheetHasBeenAdded(CharacterSheet*)), this,
0062             SLOT(addTabWithSheetView(CharacterSheet*)));*/
0063 
0064     setWindowIcon(QIcon::fromTheme("treeview"));
0065 
0066     if(m_sheetCtrl)
0067         m_ui->m_treeview->setModel(m_sheetCtrl->model());
0068 
0069     resize(m_preferences->value("charactersheetwindows/width", 400).toInt(),
0070            m_preferences->value("charactersheetwindows/height", 600).toInt());
0071     updateTitle();
0072 
0073     m_ui->m_treeview->setContextMenuPolicy(Qt::CustomContextMenu);
0074     connect(m_ui->m_treeview, &QTreeView::customContextMenuRequested, this, &CharacterSheetWindow::displayCustomMenu);
0075     connect(m_ui->m_copyTab, &QAction::triggered, this, &CharacterSheetWindow::copyTab);
0076     connect(m_ui->m_readOnlyAct, &QAction::triggered, this, &CharacterSheetWindow::setReadOnlyOnSelection);
0077     connect(m_ui->m_addLine, &QAction::triggered, this, &CharacterSheetWindow::addLine);
0078     connect(m_ui->m_addSection, &QAction::triggered, this, &CharacterSheetWindow::addSection);
0079     connect(m_ui->m_addCharactersheet, &QAction::triggered, this, &CharacterSheetWindow::addCharacterSheet);
0080     connect(m_ui->m_loadQml, &QAction::triggered, this, &CharacterSheetWindow::openQML);
0081     connect(m_ui->m_printAct, &QAction::triggered, this, &CharacterSheetWindow::exportPDF);
0082     connect(m_ui->m_detachTab, &QAction::triggered, this, &CharacterSheetWindow::detachTab);
0083     connect(m_ui->m_stopSharingTabAct, &QAction::triggered, this, &CharacterSheetWindow::stopSharing);
0084 
0085     auto button= new QToolButton(this); // tr("Actions")
0086     button->setDefaultAction(m_ui->m_menuAct);
0087     m_ui->m_tabwidget->setCornerWidget(button);
0088     button->setEnabled(false);
0089     connect(m_sheetCtrl, &CharacterSheetController::cornerEnabledChanged, button, &QToolButton::setEnabled);
0090     connect(button, &QPushButton::clicked, this,
0091             [button, this]() { contextMenuForTabs(QPoint(button->pos().x(), 0)); });
0092 }
0093 CharacterSheetWindow::~CharacterSheetWindow() {}
0094 void CharacterSheetWindow::addLine()
0095 {
0096     // m_model.addLine(m_view.currentIndex());
0097 }
0098 void CharacterSheetWindow::setReadOnlyOnSelection()
0099 {
0100     QList<QModelIndex> list= m_ui->m_treeview->selectionModel()->selectedIndexes();
0101     bool allTheSame= true;
0102     int i= 0;
0103     bool firstStatus= true;
0104     QList<CSItem*> listItem;
0105     for(auto item : list)
0106     {
0107         if(0 == item.column())
0108         {
0109             CSItem* csitem= static_cast<CSItem*>(item.internalPointer());
0110             if(nullptr == csitem)
0111                 continue;
0112 
0113             listItem.append(csitem);
0114         }
0115         else
0116         {
0117             /* CharacterSheet* sheet= m_model.getCharacterSheet(item.column() - 1);
0118                if(nullptr != sheet)
0119                {
0120                    TreeSheetItem* csitem= static_cast<TreeSheetItem*>(item.internalPointer());
0121                    if(nullptr != csitem)
0122                    {
0123                        listItem.append(sheet->getFieldFromKey(csitem->Id()));
0124                    }
0125                }*/
0126         }
0127     }
0128     for(auto csitem : listItem)
0129     {
0130         if(nullptr != csitem)
0131         {
0132             if(i == 0)
0133             {
0134                 firstStatus= csitem->isReadOnly();
0135             }
0136             if(firstStatus != csitem->isReadOnly())
0137             {
0138                 allTheSame= false;
0139             }
0140         }
0141         ++i;
0142     }
0143     bool valueToSet;
0144     if(allTheSame)
0145     {
0146         valueToSet= !firstStatus;
0147     }
0148     else
0149     {
0150         valueToSet= true;
0151     }
0152     for(auto csitem : listItem)
0153     {
0154         if(nullptr != csitem)
0155         {
0156             csitem->setReadOnly(valueToSet);
0157         }
0158     }
0159 }
0160 
0161 void CharacterSheetWindow::updateTitle()
0162 {
0163     if(m_sheetCtrl)
0164         setWindowTitle(tr("%1 - (Character Sheet Viewer)").arg(m_sheetCtrl->name()));
0165 }
0166 
0167 void CharacterSheetWindow::displayCustomMenu(const QPoint& pos)
0168 {
0169     QMenu menu(this);
0170 
0171     QModelIndex index= m_ui->m_treeview->indexAt(pos);
0172     bool isReadOnly= false;
0173     if(index.column() > 0)
0174     {
0175         QMenu* affect= menu.addMenu(m_shareTo);
0176         addSharingMenu(affect, index.column() - 1);
0177 
0178         auto childItem= dynamic_cast<CSItem*>(static_cast<TreeSheetItem*>(index.internalPointer()));
0179         if(nullptr != childItem)
0180         {
0181             isReadOnly= childItem->isReadOnly();
0182         }
0183 
0184         // childItem->();
0185     }
0186 
0187     menu.addSeparator();
0188     menu.addAction(m_ui->m_readOnlyAct);
0189     m_ui->m_readOnlyAct->setChecked(isReadOnly);
0190     /*menu.addSeparator();
0191     menu.addAction(m_addLine);
0192     menu.addAction(m_addSection);
0193     menu.addAction(m_addCharacterSheet);
0194     menu.addSeparator();
0195     menu.addAction(m_loadQml);*/
0196 
0197     addActionToMenu(menu);
0198     menu.exec(QCursor::pos());
0199 }
0200 void CharacterSheetWindow::addSharingMenu(QMenu* share, int idx)
0201 {
0202     auto model= m_sheetCtrl->characterModel();
0203     if(!model)
0204         return;
0205     bool hasCharacter= false;
0206     for(int i= 0; i < model->rowCount(); ++i)
0207     {
0208         hasCharacter= true;
0209         auto index= model->index(i, 0, QModelIndex());
0210         auto uuid= index.data(PlayerModel::IdentifierRole).toString();
0211         auto avatar= index.data(PlayerModel::AvatarRole).value<QImage>();
0212         auto name= index.data(PlayerModel::NameRole).toString();
0213         QAction* action= share->addAction(QPixmap::fromImage(avatar), name);
0214         action->setData(uuid);
0215         connect(action, &QAction::triggered, this,
0216                 [this, uuid, idx]() { m_sheetCtrl->shareCharacterSheetTo(uuid, idx); });
0217     }
0218 
0219     if(hasCharacter)
0220     {
0221         share->addSeparator();
0222         auto act= share->addAction(tr("To all"));
0223         connect(act, &QAction::triggered, this, [this, idx]() { m_sheetCtrl->shareCharacterSheetToAll(idx); });
0224     }
0225 }
0226 
0227 void CharacterSheetWindow::contextMenuForTabs(const QPoint pos)
0228 {
0229     QMenu menu(this);
0230 
0231     QWidget* wid= m_ui->m_tabwidget->currentWidget();
0232     SheetWidget* quickWid= dynamic_cast<SheetWidget*>(wid);
0233     m_currentCharacterSheet= quickWid->sheet();
0234 
0235     if(nullptr == m_currentCharacterSheet)
0236         return;
0237 
0238     menu.addAction(m_ui->m_detachTab);
0239     QMenu* share= menu.addMenu(m_shareTo);
0240 
0241     menu.addAction(m_ui->m_copyTab);
0242     menu.addAction(m_ui->m_stopSharingTabAct);
0243     menu.addSeparator();
0244     addSharingMenu(share, m_ui->m_tabwidget->currentIndex() - 1);
0245     addActionToMenu(menu);
0246     menu.addAction(m_ui->m_printAct);
0247 
0248     menu.exec(quickWid->mapToGlobal(pos));
0249 }
0250 bool CharacterSheetWindow::eventFilter(QObject* object, QEvent* event)
0251 {
0252     if(event->type() == QEvent::Hide)
0253     {
0254         SheetWidget* wid= dynamic_cast<SheetWidget*>(object);
0255         if(nullptr != wid)
0256         {
0257             if(-1 == m_ui->m_tabwidget->indexOf(wid))
0258             {
0259                 wid->removeEventFilter(this);
0260                 m_ui->m_tabwidget->addTab(wid, wid->windowTitle());
0261             }
0262         }
0263         return MediaContainer::eventFilter(object, event);
0264     }
0265     /*else if(event->type() == QEvent::MouseButtonPress)
0266     {
0267         qDebug() << "mouse Press";
0268     }
0269     else if (event->type() == QEvent::ContextMenu)
0270     {
0271        // QQuickItem* wid = dynamic_cast<QQuickItem*>(object);
0272         auto menuEvent = dynamic_cast<QContextMenuEvent*>(event);
0273         if( nullptr != menuEvent)//nullptr != wid &&
0274         {
0275             contextMenuForTabs(menuEvent->pos());
0276         }
0277         qDebug() << "Context Menu";
0278         return false;
0279     }*/
0280     return MediaContainer::eventFilter(object, event);
0281 }
0282 
0283 void CharacterSheetWindow::stopSharing()
0284 {
0285     // SheetWidget* wid= dynamic_cast<SheetWidget*>(m_ui->m_tabwidget->currentWidget());
0286     // if(nullptr != wid)
0287     {
0288         // CharacterSheet* sheet= wid->sheet();
0289         /*        if(m_sheetToPerson.contains(sheet))
0290                 {
0291                     Player* currentPlayer= m_sheetToPerson.value(sheet);
0292                     if(nullptr == currentPlayer)
0293                         return;
0294 
0295                     NetworkMessageWriter msg(NetMsg::CharacterCategory, NetMsg::closeCharacterSheet);
0296                     QStringList recipiants;
0297                     recipiants << currentPlayer->getUuid();
0298                     msg.setRecipientList(recipiants, NetworkMessage::OneOrMany);
0299                     msg.string8(m_mediaId);
0300                     msg.string8(sheet->getUuid());
0301                     / *PlayerModel* list= PlayerModel::instance();
0302                     if(list->hasPlayer(currentPlayer))
0303                     {
0304                         msg.sendToServer();
0305                     }* /
0306                     m_sheetToPerson.remove(sheet);
0307                 }*/
0308     }
0309 }
0310 
0311 void CharacterSheetWindow::detachTab()
0312 {
0313     QWidget* wid= m_ui->m_tabwidget->currentWidget();
0314     QString title= m_ui->m_tabwidget->tabBar()->tabText(m_ui->m_tabwidget->currentIndex());
0315     m_ui->m_tabwidget->removeTab(m_ui->m_tabwidget->currentIndex());
0316     wid->installEventFilter(this);
0317     emit addWidgetToMdiArea(wid, title);
0318 }
0319 void CharacterSheetWindow::copyTab()
0320 {
0321     SheetWidget* wid= dynamic_cast<SheetWidget*>(m_ui->m_tabwidget->currentWidget());
0322     if(nullptr != wid)
0323     {
0324         CharacterSheet* sheet= wid->sheet();
0325         if(nullptr != sheet)
0326         {
0327             // addTabWithSheetView(sheet);
0328         }
0329     }
0330 }
0331 
0332 void CharacterSheetWindow::affectSheetToCharacter(const QString& uuid)
0333 {
0334     Q_UNUSED(uuid)
0335 
0336     /*Character* character= PlayerModel::instance()->getCharacter(key);
0337     if(nullptr != character)
0338     {
0339         CharacterSheet* sheet= m_currentCharacterSheet;
0340         if(sheet == nullptr)
0341             return;
0342 
0343         SheetWidget* quickWid= nullptr;
0344         for(int i= 0, total= m_ui->m_tabwidget->count(); i < total; ++i)
0345         {
0346             auto wid= dynamic_cast<SheetWidget*>(m_ui->m_tabwidget->widget(i));
0347             if(wid != nullptr && sheet == wid->sheet())
0348             {
0349                 quickWid= wid;
0350             }
0351         }
0352 
0353         checkAlreadyShare(sheet);
0354         m_sheetToCharacter.insert(sheet, character);
0355         character->setSheet(sheet);
0356         addTabWithSheetView(sheet);
0357         sheet->setName(character->name());
0358         m_ui->m_tabwidget->setTabText(m_ui->m_tabwidget->indexOf(quickWid), sheet->getName());
0359 
0360         Player* parent= character->getParentPlayer();
0361         Player* localItem= PlayerModel::instance()->getLocalPlayer();
0362         if((nullptr != parent) && (nullptr != localItem) && (localItem->isGM()))
0363         {
0364             m_sheetToPerson.insert(sheet, parent);
0365 
0366             Player* person= character->getParentPlayer();
0367             if(nullptr != person)
0368             {
0369                 NetworkMessageWriter msg(NetMsg::CharacterCategory, NetMsg::addCharacterSheet);
0370                 QStringList idList;
0371                 idList << person->getUuid();
0372                 msg.setRecipientList(idList, NetworkMessage::OneOrMany);
0373                 msg.string8(parent->getUuid());
0374                 fillMessage(&msg, sheet, character->getUuid());
0375                 msg.sendToServer();
0376             }
0377         }
0378     }*/
0379 }
0380 void CharacterSheetWindow::checkAlreadyShare(CharacterSheet* sheet)
0381 {
0382     Q_UNUSED(sheet)
0383     /* if(m_sheetToPerson.contains(sheet))
0384      {
0385          Player* olderParent= m_sheetToPerson.value(sheet);
0386          if(nullptr != olderParent)
0387          {
0388              NetworkMessageWriter msg(NetMsg::CharacterCategory, NetMsg::closeCharacterSheet);
0389              QStringList recipiants;
0390              recipiants << olderParent->getUuid();
0391              msg.setRecipientList(recipiants, NetworkMessage::OneOrMany);
0392              msg.string8(m_mediaId);
0393              msg.string8(sheet->getUuid());
0394              / *PlayerModel* list= PlayerModel::instance();
0395              if(list->hasPlayer(olderParent))
0396              {
0397                  msg.sendToServer();
0398              }* /
0399          }
0400          m_sheetToPerson.remove(sheet);
0401      }*/
0402 }
0403 bool CharacterSheetWindow::hasCharacterSheet(QString id)
0404 {
0405     Q_UNUSED(id)
0406     /*if(nullptr == m_model.getCharacterSheetById(id))
0407     {
0408         return false;
0409     }
0410     else
0411     {
0412         return true;
0413     }*/
0414     return false;
0415 }
0416 
0417 void CharacterSheetWindow::removeConnection(Player* player)
0418 {
0419     Q_UNUSED(player)
0420     /*  CharacterSheet* key= m_sheetToPerson.key(player, nullptr);
0421       if(nullptr != key)
0422       {
0423           m_sheetToPerson.remove(key);
0424       }*/
0425 }
0426 
0427 void CharacterSheetWindow::addSection()
0428 {
0429     // m_model.addSection();
0430 }
0431 void CharacterSheetWindow::addCharacterSheet()
0432 {
0433     /* m_errorList.clear();
0434      m_model.addCharacterSheet();
0435      displayError(m_errorList);*/
0436 }
0437 void CharacterSheetWindow::addTabWithSheetView(CharacterSheet* chSheet, Character* character)
0438 {
0439     if(chSheet == nullptr || nullptr == character)
0440         return;
0441 
0442     auto qmlView= new SheetWidget(this);
0443     connect(qmlView, &SheetWidget::customMenuRequested, this, &CharacterSheetWindow::contextMenuForTabs);
0444     auto imageProvider= new RolisteamImageProvider(m_sheetCtrl->imageModel());
0445     auto engineQml= qmlView->engine();
0446 
0447     engineQml->addImageProvider(QLatin1String("rcs"), imageProvider);
0448     engineQml->addImportPath(QStringLiteral("qrc:/charactersheet/qml"));
0449     engineQml->rootContext()->setContextProperty("_character", character);
0450 
0451     for(int i= 0; i < chSheet->getFieldCount(); ++i)
0452     {
0453         TreeSheetItem* field= chSheet->getFieldAt(i);
0454         if(nullptr != field)
0455         {
0456             qmlView->engine()->rootContext()->setContextProperty(field->id(), field);
0457         }
0458     }
0459 
0460     QTemporaryFile fileTemp;
0461 
0462     if(fileTemp.open()) // QIODevice::WriteOnly
0463     {
0464         fileTemp.write(m_sheetCtrl->qmlCode().toUtf8());
0465         fileTemp.close();
0466     }
0467 
0468     qmlView->setSource(QUrl::fromLocalFile(fileTemp.fileName())); // WARNING take time
0469     qmlView->setResizeMode(QQuickWidget::SizeRootObjectToView);
0470     readErrorFromQML(qmlView->errors());
0471     m_errorList.append(qmlView->errors());
0472 
0473     QObject* root= qmlView->rootObject();
0474 
0475     // CONNECTION TO SIGNAL FROM QML CHARACTERSHEET
0476     connect(root, SIGNAL(showText(QString)), m_sheetCtrl, SIGNAL(showText(QString)));
0477     connect(root, SIGNAL(rollDiceCmd(QString, bool)), m_sheetCtrl, SLOT(rollDice(QString, bool)));
0478     connect(root, SIGNAL(rollDiceCmd(QString)), m_sheetCtrl, SLOT(rollDice(QString)));
0479 
0480     qmlView->setSheet(chSheet);
0481     int id= m_ui->m_tabwidget->addTab(qmlView, chSheet->getTitle());
0482     if(!m_sheetCtrl->localGM())
0483     {
0484         m_ui->m_tabwidget->setCurrentIndex(id);
0485     }
0486 }
0487 void CharacterSheetWindow::readErrorFromQML(QList<QQmlError> list)
0488 {
0489     for(auto& error : list)
0490     {
0491         emit errorOccurs(error.toString());
0492     }
0493 }
0494 
0495 void CharacterSheetWindow::rollDice(QString str, bool alias)
0496 {
0497     QObject* obj= sender();
0498     QString label;
0499     for(int i= 0, total= m_ui->m_tabwidget->count(); i < total; ++i)
0500     {
0501         SheetWidget* qmlView= dynamic_cast<SheetWidget*>(m_ui->m_tabwidget->widget(i));
0502 
0503         if(nullptr == qmlView)
0504             continue;
0505 
0506         QObject* root= qmlView->rootObject();
0507         if(root == obj)
0508         {
0509             label= m_ui->m_tabwidget->tabText(m_ui->m_tabwidget->indexOf(qmlView));
0510         }
0511     }
0512     emit rollDiceCmd(str, label, alias);
0513 }
0514 
0515 /*void CharacterSheetWindow::processUpdateFieldMessage(NetworkMessageReader* msg, const QString& idSheet)
0516 {
0517     Q_UNUSED(msg)
0518     Q_UNUSED(idSheet)
0519     CharacterSheet* currentSheet= m_model.getCharacterSheetById(idSheet);
0520 
0521     if(nullptr == currentSheet)
0522         return;
0523 
0524     auto path= msg->string32();
0525     QByteArray array= msg->byteArray32();
0526     if(array.isEmpty())
0527         return;
0528 
0529     QJsonDocument doc= QJsonDocument::fromBinaryData(array);
0530     QJsonObject obj= doc.object();
0531     currentSheet->setFieldData(obj, path);
0532 }*/
0533 void CharacterSheetWindow::displayError(const QList<QQmlError>& warnings)
0534 {
0535     QString result= "";
0536     for(auto& error : warnings)
0537     {
0538         result+= error.toString();
0539     }
0540     if(!warnings.isEmpty())
0541     {
0542         QMessageBox::information(this, tr("QML Errors"), result, QMessageBox::Ok);
0543     }
0544 }
0545 
0546 QJsonDocument CharacterSheetWindow::saveFile()
0547 {
0548 
0549     /*if(nullptr == m_uri)
0550     {
0551         qWarning() << "no uri for charactersheet";
0552         return {};
0553     }
0554 
0555     QJsonDocument json;
0556     QJsonObject obj;
0557     auto path= m_uri->getUri();
0558 
0559     QByteArray data;
0560     if(path.isEmpty())
0561     {
0562         data= m_uri->getData();
0563     }
0564     else
0565     {
0566         QFile file(path);
0567         if(file.open(QIODevice::ReadOnly))
0568         {
0569             data= file.readAll();
0570             file.close();
0571         }
0572     }
0573 
0574     if(data.isEmpty())
0575     {
0576         qWarning() << "Charactersheet with empty data";
0577         return {};
0578     }
0579 
0580     json= QJsonDocument::fromJson(data);
0581     obj= json.object();
0582 
0583     // Get datamodel
0584     obj["data"]= m_data;
0585 
0586     // qml file
0587     // obj["qml"]=m_qmlData;*/
0588 
0589     // background
0590     /*QJsonArray images = obj["background"].toArray();
0591     for(auto key : m_pixmapList->keys())
0592     {
0593         QJsonObject obj;
0594         obj["key"]=key;
0595         obj["isBg"]=;
0596         QPixmap pix = m_pixmapList->value(key);
0597         if(!pix.isNull())
0598         {
0599             QByteArray bytes;
0600             QBuffer buffer(&bytes);
0601             buffer.open(QIODevice::WriteOnly);
0602             pix.save(&buffer, "PNG");
0603             obj["bin"]=QString(buffer.data().toBase64());
0604             images.append(obj);
0605         }
0606     }
0607     obj["background"]=images;*/
0608     /* m_model.writeModel(obj, false);
0609      json.setObject(obj);
0610      return json;*/
0611     return {};
0612 }
0613 
0614 void CharacterSheetWindow::openQML()
0615 {
0616     m_qmlUri= QFileDialog::getOpenFileName(this, tr("Open Character Sheets View"),
0617                                            m_preferences->value(QString("DataDirectory"), QVariant(".")).toString(),
0618                                            tr("Character Sheet files (*.qml)"));
0619     if(!m_qmlUri.isEmpty())
0620     {
0621         QFile file(m_qmlUri);
0622         if(file.open(QIODevice::ReadOnly))
0623         {
0624             m_sheetCtrl->setQmlCode(QString(file.readAll()));
0625         }
0626     }
0627 }
0628 
0629 void CharacterSheetWindow::closeEvent(QCloseEvent* event)
0630 {
0631     setVisible(false);
0632     event->ignore();
0633 }
0634 
0635 void CharacterSheetWindow::addCharacterSheetSlot(CharacterSheet* sheet)
0636 {
0637     if(nullptr != sheet)
0638     {
0639         // connect(sheet, &CharacterSheet::updateField, this, &CharacterSheetWindow::updateFieldFrom);
0640         //       m_model.addCharacterSheet(sheet, false);
0641     }
0642 }
0643 
0644 /*bool CharacterSheetWindow::readFileFromUri()
0645 {
0646       if(nullptr != m_uri)
0647       {
0648           updateTitle();
0649 
0650           if(m_uri->getCurrentMode() == CleverURI::Internal || !m_uri->exists())
0651           {
0652               QByteArray data= m_uri->getData();
0653               m_uri->setCurrentMode(CleverURI::Internal);
0654               QJsonDocument doc= QJsonDocument::fromBinaryData(data);
0655               return readData(doc.toJson());
0656           }
0657           else if(m_uri->getCurrentMode() == CleverURI::Linked)
0658           {
0659               return openFile(m_uri->getUri());
0660           }
0661       }
0662     return false;
0663 }
0664 void CharacterSheetWindow::putDataIntoCleverUri()
0665 {
0666     QByteArray data;
0667     QJsonDocument doc= saveFile();
0668     data= doc.toBinaryData();*/
0669 /* if(nullptr != m_uri)
0670  {
0671      m_uri->setData(data);
0672  }
0673 }
0674 
0675 void CharacterSheetWindow::saveMedia()
0676 {
0677 if((nullptr != m_uri) && (!m_uri->getUri().isEmpty()))
0678 {
0679     QString uri= m_uri->getUri();
0680     if(!uri.isEmpty())
0681     {
0682         if(!uri.endsWith(".rcs"))
0683         {
0684             uri+= QLatin1String(".rcs");
0685         }
0686         QJsonDocument doc= saveFile();
0687         QFile file(uri);
0688         if(file.open(QIODevice::WriteOnly))
0689         {
0690             file.write(doc.toJson());
0691             file.close();
0692         }
0693     }
0694 }
0695 }
0696 void CharacterSheetWindow::fillMessage(NetworkMessageWriter* msg, CharacterSheet* sheet, QString idChar)
0697 {
0698     Q_UNUSED(msg)
0699     Q_UNUSED(sheet)
0700     Q_UNUSED(idChar)
0701     msg->string8(m_mediaId);
0702     msg->string8(idChar);
0703     msg->string8(getUriName());
0704 
0705     if(nullptr != sheet)
0706     {
0707         sheet->fill(*msg);
0708     }
0709     msg->string32(m_qmlData);
0710     //   m_imageModel->fill(*msg);
0711 
0712     //  m_model.fillRootSection(msg);
0713 }
0714 
0715 void CharacterSheetWindow::readMessage(NetworkMessageReader& msg)
0716 {
0717     Q_UNUSED(msg)
0718     CharacterSheet* sheet= new CharacterSheet();
0719 
0720     m_mediaId= msg.string8();
0721     QString idChar= msg.string8();
0722     setUriName(msg.string8());
0723 
0724     if(nullptr != sheet)
0725     {
0726         sheet->read(msg);
0727     }*/
0728 // m_qmlData= msg.string32();
0729 //  m_imageModel->read(msg);
0730 
0731 /*Character* character= PlayerModel::instance()->getCharacter(idChar);
0732 m_sheetToCharacter.insert(sheet, character);
0733 
0734 addCharacterSheet(sheet);
0735 m_model.readRootSection(&msg);
0736 if(nullptr != character)
0737 {
0738     character->setSheet(sheet);
0739 }
0740 }*/
0741 
0742 void CharacterSheetWindow::exportPDF()
0743 {
0744     auto qmlView= qobject_cast<SheetWidget*>(m_ui->m_tabwidget->currentWidget());
0745 
0746     if(nullptr == qmlView)
0747         return;
0748 
0749     QObject* root= qmlView->rootObject();
0750     if(nullptr == root)
0751         return;
0752 
0753     auto maxPage= QQmlProperty::read(root, "maxPage").toInt();
0754     auto currentPage= QQmlProperty::read(root, "page").toInt();
0755     auto sheetW= QQmlProperty::read(root, "width").toReal();
0756     auto sheetH= QQmlProperty::read(root, "height").toReal();
0757 
0758     QObject* imagebg= root->findChild<QObject*>("imagebg");
0759     if(nullptr != imagebg)
0760     {
0761         sheetW= QQmlProperty::read(imagebg, "width").toReal();
0762         sheetH= QQmlProperty::read(imagebg, "height").toReal();
0763     }
0764     else
0765     {
0766         sheetW= width();
0767         sheetH= height();
0768     }
0769     QPrinter printer;
0770     QPrintDialog dialog(&printer, this);
0771     if(dialog.exec() == QDialog::Accepted)
0772     {
0773         QPainter painter;
0774         if(painter.begin(&printer))
0775         {
0776             for(int i= 0; i <= maxPage; ++i)
0777             {
0778                 root->setProperty("page", i);
0779                 QTimer timer;
0780                 timer.setSingleShot(true);
0781                 QEventLoop loop;
0782                 connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
0783                 timer.start(m_preferences->value("waitingTimeBetweenPage", 300).toInt());
0784                 loop.exec();
0785 
0786                 auto image= qmlView->grabFramebuffer();
0787                 QRectF rect(0, 0, printer.width(), printer.height());
0788                 QRectF source(0.0, 0.0, sheetW, sheetH);
0789                 painter.drawImage(rect, image, source);
0790                 if(i != maxPage)
0791                     printer.newPage();
0792             }
0793             painter.end();
0794         }
0795     }
0796     root->setProperty("page", currentPage);
0797 }