File indexing completed on 2024-04-28 04:37:31

0001 /*
0002     SPDX-FileCopyrightText: 2006-2007 Alexander Dymo <adymo@kdevelop.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "document.h"
0008 
0009 #include "view.h"
0010 #include "area.h"
0011 #include "controller.h"
0012 // Qt
0013 #include <QIcon>
0014 
0015 namespace Sublime {
0016 
0017 // class DocumentPrivate
0018 
0019 class DocumentPrivate
0020 {
0021 public:
0022     DocumentPrivate(Controller* controller, Document* doc)
0023         : controller(controller)
0024         , document(doc)
0025     {}
0026 
0027     void removeView(Sublime::View* view)
0028     {
0029         views.removeAll(view);
0030         //no need to keep empty document - we need to remove it
0031         if (views.count() == 0)
0032         {
0033             emit document->aboutToDelete(document);
0034             document->deleteLater();
0035         }
0036     }
0037 
0038     QList<View*> views;
0039     QIcon statusIcon;
0040     QString documentToolTip;
0041 
0042     Controller* const controller;
0043     Document* const document;
0044 };
0045 
0046 
0047 
0048 //class Document
0049 
0050 Document::Document(const QString &title, Controller *controller)
0051     : QObject(controller)
0052     , d_ptr(new DocumentPrivate(controller, this))
0053 {
0054     Q_D(Document);
0055 
0056     setObjectName(title);
0057     d->controller->addDocument(this);
0058     // Functor will be called after destructor has run -> capture controller pointer by value
0059     // otherwise we crash because we access the already freed pointer this->d
0060     connect(this, &Document::destroyed, d->controller, [controller, this](QObject* obj) {
0061         Q_ASSERT(obj == this);
0062         controller->removeDocument(this);
0063     });
0064 }
0065 
0066 Document::~Document() = default;
0067 
0068 Controller *Document::controller() const
0069 {
0070     Q_D(const Document);
0071 
0072     return d->controller;
0073 }
0074 
0075 View *Document::createView()
0076 {
0077     Q_D(Document);
0078 
0079     View *view = newView(this);
0080     connect(view, &View::destroyed, this, [this, view](QObject* obj) {
0081         Q_D(Document);
0082         Q_ASSERT(obj == view);
0083         d->removeView(view);
0084     });
0085     d->views.append(view);
0086     return view;
0087 }
0088 
0089 const QList<View*> &Document::views() const
0090 {
0091     Q_D(const Document);
0092 
0093     return d->views;
0094 }
0095 
0096 QString Document::title(TitleType /*type*/) const
0097 {
0098     return objectName();
0099 }
0100 
0101 QString Document::toolTip() const
0102 {
0103     Q_D(const Document);
0104 
0105     return d->documentToolTip;
0106 }
0107 
0108 void Document::setTitle(const QString& newTitle)
0109 {
0110     setObjectName(newTitle);
0111     emit titleChanged(this);
0112 }
0113 
0114 void Document::setToolTip(const QString& newToolTip)
0115 {
0116     Q_D(Document);
0117 
0118     d->documentToolTip=newToolTip;
0119 }
0120 
0121 View *Document::newView(Document *doc)
0122 {
0123     //first create View, second emit the signal
0124     View *newView = new View(doc);
0125     return newView;
0126 }
0127 
0128 
0129 void Document::setStatusIcon(const QIcon& icon)
0130 {
0131     Q_D(Document);
0132 
0133     d->statusIcon = icon;
0134     emit statusIconChanged(this);
0135 }
0136 
0137 QIcon Document::statusIcon() const
0138 {
0139     Q_D(const Document);
0140 
0141     return d->statusIcon;
0142 }
0143 
0144 void Document::closeViews()
0145 {
0146     for (Sublime::Area* area : controller()->allAreas()) {
0147         const QList<Sublime::View*> areaViews = area->views();
0148         for (Sublime::View* view : areaViews) {
0149             if (views().contains(view)) {
0150                 area->removeView(view);
0151                 delete view;
0152             }
0153         }
0154     }
0155     Q_ASSERT(views().isEmpty());
0156 }
0157 
0158 bool Document::askForCloseFeedback()
0159 {
0160    return true;
0161 }
0162 
0163 bool Document::closeDocument(bool silent)
0164 {
0165     if( !silent && !askForCloseFeedback() )
0166         return false;
0167     closeViews();
0168     deleteLater();
0169     return true;
0170 }
0171 
0172 QIcon Document::icon() const
0173 {
0174     QIcon ret = statusIcon();
0175     if (!ret.isNull()) {
0176         return ret;
0177     }
0178     return defaultIcon();
0179 }
0180 
0181 QIcon Document::defaultIcon() const
0182 {
0183     return QIcon();
0184 }
0185 
0186 }
0187 
0188 #include "moc_document.cpp"