File indexing completed on 2024-05-12 17:12:41
0001 /*************************************************************************** 0002 * Copyright (C) 2007 by Romain Campioni * 0003 * Copyright (C) 2009 by Renaud Guezennec * 0004 * https://rolisteam.org/contact * 0005 * * 0006 * rolisteam is free software; you can redistribute it and/or modify * 0007 * it under the terms of the GNU General Public License as published by * 0008 * the Free Software Foundation; either version 2 of the License, or * 0009 * (at your option) any later version. * 0010 * * 0011 * This program is distributed in the hope that it will be useful, * 0012 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0014 * GNU General Public License for more details. * 0015 * * 0016 * You should have received a copy of the GNU General Public License * 0017 * along with this program; if not, write to the * 0018 * Free Software Foundation, Inc., * 0019 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 0020 ***************************************************************************/ 0021 #include "workspace.h" 0022 0023 #include <QQmlEngine> 0024 #include <QtGui> 0025 0026 #include "controller/contentcontroller.h" 0027 #include "controller/view_controller/charactersheetcontroller.h" 0028 #include "controller/view_controller/imagecontroller.h" 0029 #include "controller/view_controller/mindmapcontroller.h" 0030 #include "controller/view_controller/notecontroller.h" 0031 #include "controller/view_controller/sharednotecontroller.h" 0032 #include "controller/view_controller/vectorialmapcontroller.h" 0033 #include "controller/view_controller/webpagecontroller.h" 0034 #include "controller/view_controller/pdfcontroller.h" 0035 #include "mediacontainers/pdfviewer.h" 0036 #include "controller/instantmessagingcontroller.h" 0037 #include "mediacontainers/instantmessagingview.h" 0038 #include "editors/noteeditor/src/notecontainer.h" 0039 #include "editors/sharededitor/sharednotecontainer.h" 0040 #include "mediacontainers/charactersheetwindow.h" 0041 #include "mediacontainers/image.h" 0042 #include "mediacontainers/mindmapview.h" 0043 #include "mediacontainers/vmapframe.h" 0044 #include "mediacontainers/webview.h" 0045 0046 #define GRAY_SCALE 191 0047 0048 Workspace::Workspace(QToolBar* toolbar, ContentController* ctrl, InstantMessagingController* instantCtrl, 0049 QWidget* parent) 0050 : QMdiArea(parent), m_ctrl(ctrl), m_variableSizeBackground(size()), m_toolbar(toolbar) 0051 { 0052 connect(m_ctrl, &ContentController::maxLengthTabNameChanged, this, &Workspace::updateTitleTab); 0053 connect(m_ctrl, &ContentController::shortTitleTabChanged, this, &Workspace::updateTitleTab); 0054 connect(m_ctrl, &ContentController::workspaceFilenameChanged, this, 0055 [this]() 0056 { 0057 m_backgroundPicture= QPixmap(m_ctrl->workspaceFilename()); 0058 updateBackGround(); 0059 }); 0060 connect(m_ctrl, &ContentController::workspaceColorChanged, this, &Workspace::updateBackGround); 0061 connect(m_ctrl, &ContentController::workspacePositioningChanged, this, &Workspace::updateBackGround); 0062 0063 connect(m_ctrl, &ContentController::mediaControllerCreated, this, &Workspace::addMedia); 0064 connect(this, &Workspace::subWindowActivated, this, &Workspace::updateActiveMediaContainer); 0065 0066 if(instantCtrl) 0067 { 0068 m_instantMessageView= addSubWindow(new InstantMessagingView(instantCtrl)); 0069 m_instantMessageView->setGeometry(0, 0, 400, 600); 0070 m_instantMessageView->setAttribute(Qt::WA_DeleteOnClose, false); 0071 m_instantMessageView->setWindowIcon(QIcon::fromTheme("chaticon")); 0072 connect(instantCtrl, &InstantMessagingController::visibleChanged, m_instantMessageView, 0073 &QMdiSubWindow::setVisible); 0074 m_instantMessageView->setVisible(instantCtrl->visible()); 0075 0076 m_prevent.reset(new PreventClosing(m_instantMessageView)); 0077 connect(m_prevent.get(), &PreventClosing::visibilityObjectChanged, instantCtrl, 0078 &InstantMessagingController::setVisible); 0079 } 0080 if(m_ctrl) 0081 m_backgroundPicture= QPixmap(m_ctrl->workspaceFilename()); 0082 updateBackGround(); 0083 } 0084 0085 Workspace::~Workspace() 0086 { 0087 /*if(nullptr != m_actionSubWindowMap) 0088 { 0089 delete m_actionSubWindowMap; 0090 m_actionSubWindowMap= nullptr; 0091 }*/ 0092 } 0093 0094 void Workspace::updateBackGround() 0095 { 0096 if(!m_ctrl) 0097 return; 0098 QBrush background; 0099 background.setColor(m_ctrl->workspaceColor()); 0100 setBackground(background); 0101 0102 m_variableSizeBackground= m_variableSizeBackground.scaled(size()); 0103 m_variableSizeBackground.fill(m_ctrl->workspaceColor()); 0104 QPainter painter(&m_variableSizeBackground); 0105 0106 int x= 0; 0107 int y= 0; 0108 int w= m_backgroundPicture.width(); 0109 int h= m_backgroundPicture.height(); 0110 bool repeated= false; 0111 switch(m_ctrl->workspacePositioning()) 0112 { 0113 case TopLeft: 0114 break; 0115 case BottomLeft: 0116 y= m_variableSizeBackground.size().height() - h; 0117 break; 0118 case Center: 0119 x= m_variableSizeBackground.width() / 2 - w / 2; 0120 y= m_variableSizeBackground.height() / 2 - h / 2; 0121 break; 0122 case TopRight: 0123 x= m_variableSizeBackground.width() - w; 0124 break; 0125 case BottomRight: 0126 x= m_variableSizeBackground.width() - w; 0127 y= m_variableSizeBackground.height() - h; 0128 break; 0129 case Scaled: 0130 { 0131 qreal rd= static_cast<qreal>(w) / static_cast<qreal>(h); 0132 if(rd > 1) 0133 { 0134 w= m_variableSizeBackground.width(); 0135 h= static_cast<int>(w / rd); 0136 } 0137 else 0138 { 0139 h= m_variableSizeBackground.height(); 0140 w= static_cast<int>(h / rd); 0141 } 0142 x= m_variableSizeBackground.width() / 2 - w / 2; 0143 y= m_variableSizeBackground.height() / 2 - h / 2; 0144 } 0145 break; 0146 case Filled: 0147 w= m_variableSizeBackground.width(); 0148 h= m_variableSizeBackground.height(); 0149 break; 0150 case Repeated: 0151 repeated= true; 0152 break; 0153 } 0154 if(!repeated) 0155 { 0156 painter.drawPixmap(x, y, w, h, m_backgroundPicture); 0157 setBackground(QBrush(m_variableSizeBackground)); 0158 } 0159 else 0160 { 0161 setBackground(QBrush(m_backgroundPicture)); 0162 } 0163 update(); 0164 } 0165 0166 void Workspace::resizeEvent(QResizeEvent* event) 0167 { 0168 Q_UNUSED(event) 0169 if((m_variableSizeBackground.size() == this->size())) 0170 { 0171 return; 0172 } 0173 0174 updateBackGround(); 0175 0176 QMdiArea::resizeEvent(event); 0177 } 0178 0179 void Workspace::addContainerMedia(MediaContainer* mediac) 0180 { 0181 if(nullptr == mediac) 0182 return; 0183 0184 addSubWindow(mediac); 0185 if(viewMode() == QMdiArea::TabbedView) 0186 { 0187 mediac->setVisible(true); 0188 } 0189 mediac->setAttribute(Qt::WA_DeleteOnClose, false); 0190 if(nullptr != mediac->widget()) 0191 { 0192 mediac->widget()->setAttribute(Qt::WA_DeleteOnClose, false); 0193 } 0194 mediac->installEventFilter(this); 0195 } 0196 void Workspace::removeMediaContainer(MediaContainer* mediac) 0197 { 0198 removeSubWindow(mediac); 0199 mediac->removeEventFilter(this); 0200 } 0201 0202 void Workspace::setTabbedMode(bool isTabbed) 0203 { 0204 if(!isTabbed) 0205 { 0206 setViewMode(QMdiArea::SubWindowView); 0207 updateTitleTab(); 0208 return; 0209 } 0210 0211 setViewMode(QMdiArea::TabbedView); 0212 // setTabsClosable ( true ); 0213 setTabsMovable(true); 0214 setTabPosition(QTabWidget::North); 0215 /// make all subwindows visible. 0216 /*auto keys= m_actionSubWindowMap->keys(); 0217 for(QAction* act : keys) 0218 { 0219 auto tmp= m_actionSubWindowMap->value(act); 0220 if(nullptr == tmp) 0221 { 0222 0223 tmp->setVisible(true); 0224 if(nullptr != act) 0225 { 0226 act->setChecked(true); 0227 } 0228 if(nullptr != tmp->widget()) 0229 { 0230 tmp->widget()->setVisible(true); 0231 } 0232 } 0233 }*/ 0234 updateTitleTab(); 0235 } 0236 bool Workspace::updateTitleTab() 0237 { 0238 bool shortName= m_ctrl->shortTitleTab(); // m_preferences->value("shortNameInTabMode", false).toBool(); 0239 int textLength= m_ctrl->maxLengthTabName(); 0240 if((viewMode() == QMdiArea::TabbedView) && (shortName)) 0241 { 0242 /*auto values= m_actionSubWindowMap->values(); 0243 for(auto& subwindow : values) 0244 { 0245 auto title= subwindow->windowTitle(); 0246 if(title.size() > textLength) 0247 { 0248 m_titleBar.insert(subwindow, title); 0249 title= title.left(textLength); 0250 subwindow->setWindowTitle(title); 0251 } 0252 }*/ 0253 } 0254 else 0255 { 0256 auto keys= m_titleBar.keys(); 0257 for(auto& key : keys) 0258 { 0259 auto title= m_titleBar.value(key); 0260 key->setWindowTitle(title); 0261 } 0262 m_titleBar.clear(); 0263 } 0264 return true; 0265 } 0266 bool Workspace::eventFilter(QObject* object, QEvent* event) 0267 { 0268 if(event->type() == QEvent::Close) 0269 { 0270 QMdiSubWindow* sub= dynamic_cast<QMdiSubWindow*>(object); 0271 if(nullptr != sub) 0272 { 0273 sub->setVisible(false); 0274 event->accept(); 0275 return true; 0276 } 0277 } 0278 return QMdiArea::eventFilter(object, event); 0279 } 0280 0281 QVector<QMdiSubWindow*> Workspace::getAllSubWindowFromId(const QString& id) const 0282 { 0283 QVector<QMdiSubWindow*> vector; 0284 0285 for(auto& tmp : subWindowList()) 0286 { 0287 if(nullptr != tmp->widget()) 0288 { 0289 MediaContainer* tmpWindow= dynamic_cast<MediaContainer*>(tmp); 0290 if(nullptr != tmpWindow) 0291 { 0292 if(tmpWindow->mediaId() == id) 0293 { 0294 vector.append(tmp); 0295 } 0296 } 0297 } 0298 } 0299 return vector; 0300 } 0301 0302 bool Workspace::closeAllSubs() 0303 { 0304 std::for_each(m_mediaContainers.begin(), m_mediaContainers.end(), 0305 [this](const std::unique_ptr<MediaContainer>& media) { closeSub(media.get()); }); 0306 0307 return true; 0308 } 0309 0310 void Workspace::closeActiveSub() 0311 { 0312 m_ctrl->closeCurrentMedia(); 0313 } 0314 0315 bool Workspace::closeSub(MediaContainer* container) 0316 { 0317 if(!container) 0318 return false; 0319 0320 auto ctrl= m_activeMediaContainer->ctrl(); 0321 0322 ctrl->askToClose(); 0323 return true; 0324 } 0325 0326 void Workspace::updateActiveMediaContainer(QMdiSubWindow* window) 0327 { 0328 auto activeMediaContainer= dynamic_cast<MediaContainer*>(window); 0329 0330 if(m_activeMediaContainer == activeMediaContainer) 0331 return; 0332 0333 if(!m_activeMediaContainer.isNull()) 0334 { 0335 auto ctrl= m_activeMediaContainer->ctrl(); 0336 if(ctrl) 0337 ctrl->setActive(false); 0338 } 0339 0340 if(nullptr != activeMediaContainer) 0341 { 0342 auto ctrl= activeMediaContainer->ctrl(); 0343 ctrl->setActive(true); 0344 if(activeMediaContainer->getContainerType() == MediaContainer::ContainerType::VMapContainer) 0345 emit vmapActive(); 0346 } 0347 0348 m_activeMediaContainer= activeMediaContainer; 0349 } 0350 0351 void Workspace::addMedia(MediaControllerBase* ctrl) 0352 { 0353 switch(ctrl->contentType()) 0354 { 0355 // case Core::ContentType::ONLINEPICTURE: 0356 case Core::ContentType::PICTURE: 0357 addImage(dynamic_cast<ImageController*>(ctrl)); 0358 break; 0359 case Core::ContentType::WEBVIEW: 0360 addWebpage(dynamic_cast<WebpageController*>(ctrl)); 0361 break; 0362 case Core::ContentType::PDF: 0363 addPdf(dynamic_cast<PdfController*>(ctrl)); 0364 break; 0365 case Core::ContentType::NOTES: 0366 addNote(dynamic_cast<NoteController*>(ctrl)); 0367 break; 0368 case Core::ContentType::SHAREDNOTE: 0369 addSharedNote(dynamic_cast<SharedNoteController*>(ctrl)); 0370 break; 0371 case Core::ContentType::VECTORIALMAP: 0372 addVectorialMap(dynamic_cast<VectorialMapController*>(ctrl)); 0373 break; 0374 case Core::ContentType::CHARACTERSHEET: 0375 addCharacterSheet(dynamic_cast<CharacterSheetController*>(ctrl)); 0376 break; 0377 case Core::ContentType::MINDMAP: 0378 addMindMap(dynamic_cast<MindMapController*>(ctrl)); 0379 break; 0380 default: 0381 break; 0382 } 0383 } 0384 0385 void Workspace::addWindowAction(const QString& name, MediaContainer* window) 0386 { 0387 auto act= m_toolbar->addAction(window->windowIcon(), name); 0388 act->setCheckable(true); 0389 act->setChecked(true); 0390 0391 auto ctrl= window->ctrl(); 0392 0393 connect(act, &QAction::triggered, window, &MediaContainer::setVisible); 0394 connect(window, &MediaContainer::visibleChanged, act, &QAction::setChecked); 0395 connect(ctrl, &MediaControllerBase::nameChanged, act, &QAction::setText); 0396 connect(ctrl, &MediaControllerBase::destroyed, act, &QAction::deleteLater); 0397 } 0398 0399 void Workspace::addWidgetToMdi(MediaContainer* wid, const QString& title) 0400 { 0401 wid->setParent(this); 0402 QMdiSubWindow* sub= addSubWindow(wid); 0403 addWindowAction(title, wid); 0404 sub->setVisible(true); 0405 wid->setVisible(true); 0406 } 0407 void Workspace::addImage(ImageController* ctrl) 0408 { 0409 if(nullptr == ctrl) 0410 return; 0411 std::unique_ptr<MediaContainer> img(new Image(ctrl)); 0412 addWidgetToMdi(img.get(), ctrl->name()); 0413 m_mediaContainers.push_back(std::move(img)); 0414 } 0415 void Workspace::addVectorialMap(VectorialMapController* ctrl) 0416 { 0417 if(nullptr == ctrl) 0418 return; 0419 std::unique_ptr<MediaContainer> vmapFrame(new VMapFrame(ctrl)); 0420 vmapFrame->setGeometry(0, 0, 800, 600); 0421 addWidgetToMdi(vmapFrame.get(), ctrl->name()); 0422 m_mediaContainers.push_back(std::move(vmapFrame)); 0423 } 0424 void Workspace::addCharacterSheet(CharacterSheetController* ctrl) 0425 { 0426 if(nullptr == ctrl) 0427 return; 0428 std::unique_ptr<CharacterSheetWindow> window(new CharacterSheetWindow(ctrl)); 0429 addWidgetToMdi(window.get(), ctrl->name()); 0430 m_mediaContainers.push_back(std::move(window)); 0431 } 0432 0433 void Workspace::addWebpage(WebpageController* ctrl) 0434 { 0435 if(nullptr == ctrl) 0436 return; 0437 std::unique_ptr<WebView> window(new WebView(ctrl)); 0438 addWidgetToMdi(window.get(), ctrl->name()); 0439 m_mediaContainers.push_back(std::move(window)); 0440 } 0441 0442 void Workspace::addNote(NoteController* ctrl) 0443 { 0444 if(nullptr == ctrl) 0445 return; 0446 std::unique_ptr<NoteContainer> SharedNote(new NoteContainer(ctrl)); 0447 SharedNote->setGeometry(0, 0, 800, 600); 0448 addWidgetToMdi(SharedNote.get(), ctrl->name()); 0449 m_mediaContainers.push_back(std::move(SharedNote)); 0450 } 0451 0452 void Workspace::addMindMap(MindMapController* ctrl) 0453 { 0454 if(nullptr == ctrl) 0455 return; 0456 std::unique_ptr<MindMapView> mindMapView(new MindMapView(ctrl)); 0457 mindMapView->setGeometry(0, 0, 800, 600); 0458 addWidgetToMdi(mindMapView.get(), ctrl->name()); 0459 m_mediaContainers.push_back(std::move(mindMapView)); 0460 } 0461 0462 void Workspace::addSharedNote(SharedNoteController* ctrl) 0463 { 0464 if(nullptr == ctrl) 0465 return; 0466 std::unique_ptr<SharedNoteContainer> SharedNote(new SharedNoteContainer(ctrl)); 0467 SharedNote->setGeometry(0, 0, 800, 600); 0468 addWidgetToMdi(SharedNote.get(), ctrl->name()); 0469 m_mediaContainers.push_back(std::move(SharedNote)); 0470 } 0471 0472 void Workspace::addPdf(PdfController* ctrl) 0473 { 0474 if(nullptr == ctrl) 0475 return; 0476 std::unique_ptr<PdfViewer> pdfViewer(new PdfViewer(ctrl)); 0477 addWidgetToMdi(pdfViewer.get(), ctrl->name()); 0478 m_mediaContainers.push_back(std::move(pdfViewer)); 0479 } 0480 0481 PreventClosing::PreventClosing(QObject* watched, QObject* parent) : QObject(parent), m_watched(watched) 0482 { 0483 if(m_watched) 0484 m_watched->installEventFilter(this); 0485 } 0486 0487 bool PreventClosing::eventFilter(QObject* obj, QEvent* event) 0488 { 0489 if(obj == m_watched && event->type() == QEvent::Hide) 0490 { 0491 event->accept(); 0492 emit visibilityObjectChanged(false); 0493 return true; 0494 } 0495 else 0496 return QObject::eventFilter(obj, event); 0497 }