File indexing completed on 2024-05-19 13:33:00

0001 /***************************************************************************
0002  *   Copyright (C) 2005 by David Saxton                                    *
0003  *   david@bluehaze.org                                                    *
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 
0011 #include "document.h"
0012 #include "docmanager.h"
0013 #include "documentiface.h"
0014 #include "ktechlab.h"
0015 #include "projectmanager.h"
0016 #include "view.h"
0017 #include "viewcontainer.h"
0018 
0019 #include <KLocalizedString>
0020 #include <KMessageBox>
0021 
0022 #include <QFileDialog>
0023 #include <QTabWidget>
0024 #include <QDebug>
0025 
0026 Document::Document(const QString &caption)
0027     : QObject(KTechlab::self())
0028     , b_modified(false)
0029     , m_pDocumentIface(nullptr)
0030     , m_bDeleted(false)
0031     , m_pActiveView(nullptr)
0032     , m_caption(caption)
0033     , m_bAddToProjectOnSave(false)
0034     , m_dcopID(0)
0035     , m_nextViewID(0)
0036 {
0037     connect(KTechlab::self(), &KTechlab::configurationChanged, this, &Document::slotUpdateConfiguration);
0038 }
0039 
0040 Document::~Document()
0041 {
0042     m_bDeleted = true;
0043 
0044     ViewList viewsToDelete = m_viewList;
0045     const ViewList::iterator end = viewsToDelete.end();
0046     for (ViewList::iterator it = viewsToDelete.begin(); it != end; ++it)
0047         (*it)->deleteLater();
0048 }
0049 
0050 void Document::handleNewView(View *view)
0051 {
0052     if (!view || m_viewList.contains(view))
0053         return;
0054 
0055     m_viewList.append(view);
0056     view->setDCOPID(m_nextViewID++);
0057     view->setWindowTitle(m_caption);
0058     connect(view, &View::destroyed, this, &Document::slotViewDestroyed);
0059     connect(view, &View::focused, this, &Document::slotViewFocused);
0060     connect(view, &View::unfocused, this, &Document::viewUnfocused);
0061 
0062     view->show();
0063 
0064     if (!DocManager::self()->getFocusedView())
0065         view->setFocus();
0066 }
0067 
0068 void Document::slotViewDestroyed(QObject *obj)
0069 {
0070     View *view = static_cast<View *>(obj);
0071 
0072     m_viewList.removeAll(view);
0073 
0074     if (m_pActiveView == static_cast<QPointer<View> >(view)) {
0075         m_pActiveView = nullptr;
0076         emit viewUnfocused();
0077     }
0078 
0079     if (m_viewList.isEmpty())
0080         deleteLater();
0081 }
0082 
0083 void Document::slotViewFocused(View *view)
0084 {
0085     if (!view)
0086         return;
0087 
0088     m_pActiveView = view;
0089     emit viewFocused(view);
0090 }
0091 
0092 void Document::setCaption(const QString &caption)
0093 {
0094     m_caption = caption;
0095     const ViewList::iterator end = m_viewList.end();
0096     for (ViewList::iterator it = m_viewList.begin(); it != end; ++it)
0097         (*it)->setWindowTitle(caption);
0098 }
0099 
0100 bool Document::getURL(const QString &types, const QString &fileExtToEnforce)
0101 {
0102     QUrl url = QFileDialog::getSaveFileUrl(KTechlab::self(), i18n("Save Location"), QUrl(), types);
0103 
0104     if (url.isEmpty())
0105         return false;
0106 
0107     if (url.isLocalFile() && QFile::exists(url.toLocalFile())) {
0108         int query = KMessageBox::warningYesNo(KTechlab::self(), i18n("A file named \"%1\" already exists. Are you sure you want to overwrite it?", url.fileName()), i18n("Overwrite File?"));
0109         if (query == KMessageBox::No)
0110             return false;
0111     }
0112 
0113     if (!url.fileName().endsWith(fileExtToEnforce)) {
0114         QUrl newUrl = QUrl( url.url().append(fileExtToEnforce) );
0115         qInfo() << "Document::getURL: overriding URL without extension '" << url.toString() << "' with '" << newUrl << "'";
0116         url = newUrl;
0117     }
0118     qInfo() << "Document::getURL: in types='" << types << "', out url='" << url.toString() << "'";
0119 
0120     setURL(url);
0121 
0122     return true;
0123 }
0124 
0125 bool Document::fileClose()
0126 {
0127     if (isModified()) {
0128         // If the filename is empty then it must  be an untitled file.
0129         QString name = m_url.fileName().isEmpty() ? caption() : m_url.fileName();
0130 
0131         if (ViewContainer *viewContainer = (activeView() ? activeView()->viewContainer() : nullptr))
0132             KTechlab::self()->tabWidget()->setCurrentIndex(KTechlab::self()->tabWidget()->indexOf(viewContainer));
0133 
0134         int choice = KMessageBox::warningYesNoCancel(KTechlab::self(), i18n("The document \'%1\' has been modified.\nDo you want to save it?", name), i18n("Save Document?"), KStandardGuiItem::save(), KStandardGuiItem::discard());
0135 
0136         if (choice == KMessageBox::Cancel)
0137             return false;
0138         if (choice == KMessageBox::Yes)
0139             fileSave();
0140     }
0141 
0142     deleteLater();
0143     return true;
0144 }
0145 
0146 void Document::setModified(bool modified)
0147 {
0148     if (b_modified == modified)
0149         return;
0150 
0151     b_modified = modified;
0152 
0153     if (!m_bDeleted)
0154         emit modifiedStateChanged();
0155 }
0156 
0157 void Document::setURL(const QUrl &url)
0158 {
0159     if (m_url == url)
0160         return;
0161 
0162     bool wasEmpty = m_url.isEmpty();
0163     m_url = url;
0164 
0165     if (wasEmpty && m_bAddToProjectOnSave && ProjectManager::self()->currentProject())
0166         ProjectManager::self()->currentProject()->addFile(m_url);
0167 
0168     emit fileNameChanged(url);
0169 
0170     if (KTechlab::self()) {
0171         KTechlab::self()->addRecentFile(url);
0172         KTechlab::self()->requestUpdateCaptions();
0173     }
0174 }
0175 
0176 DCOPObject *Document::dcopObject() const
0177 {
0178     return m_pDocumentIface;
0179 }
0180 
0181 void Document::setDCOPID(unsigned id)
0182 {
0183     if (m_dcopID == id)
0184         return;
0185 
0186     m_dcopID = id;
0187     if (m_pDocumentIface) {
0188         QString docID;
0189         docID.setNum(dcopID());
0190         m_pDocumentIface->setObjId("Document#" + docID);
0191     }
0192 }
0193 
0194 #include "moc_document.cpp"