kateproject.cpp 5.65 KB
Newer Older
Christoph Cullmann's avatar
Christoph Cullmann committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/*  This file is part of the Kate project.
 *
 *  Copyright (C) 2012 Christoph Cullmann <cullmann@kde.org>
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Library General Public
 *  License as published by the Free Software Foundation; either
 *  version 2 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Library General Public License for more details.
 *
 *  You should have received a copy of the GNU Library General Public License
 *  along with this library; see the file COPYING.LIB.  If not, write to
 *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 *  Boston, MA 02110-1301, USA.
 */

#include "kateproject.h"
22
#include "kateprojectworker.h"
Christoph Cullmann's avatar
Christoph Cullmann committed
23

24 25
#include <ktexteditor/document.h>

Christoph Cullmann's avatar
Christoph Cullmann committed
26
#include <QDir>
Christoph Cullmann's avatar
Christoph Cullmann committed
27
#include <QFile>
Christoph Cullmann's avatar
Christoph Cullmann committed
28
#include <QFileInfo>
29
#include <QPlainTextDocumentLayout>
Christoph Cullmann's avatar
Christoph Cullmann committed
30 31
#include <qjson/parser.h>

Christoph Cullmann's avatar
Christoph Cullmann committed
32 33
KateProject::KateProject ()
  : QObject ()
34
  , m_worker (new KateProjectWorker (this))
35
  , m_thread (m_worker)
36
  , m_notesDocument(0)
37
{
Christoph Cullmann's avatar
Christoph Cullmann committed
38
  /**
39
   * move worker object over and start our worker thread
40
   * thread will delete worker on run() exit
Christoph Cullmann's avatar
Christoph Cullmann committed
41
   */
42 43
  m_worker->moveToThread (&m_thread);
  m_thread.start ();
Christoph Cullmann's avatar
Christoph Cullmann committed
44 45 46
}

KateProject::~KateProject ()
47 48 49 50 51
{
  /**
   * only do this once
   */
  Q_ASSERT (m_worker);
52

Christoph Cullmann's avatar
Christoph Cullmann committed
53
  /**
54
   * quit the thread event loop and wait for completion
55
   * will delete worker on thread run() exit
Christoph Cullmann's avatar
Christoph Cullmann committed
56
   */
57 58
  m_thread.quit ();
  m_thread.wait ();
59

60
  /**
61
   * marks as deleted
62
   */
63
  m_worker = 0;
64
  
65 66 67 68
  /**
   * save notes document, if any
   */
  saveNotesDocument ();
Christoph Cullmann's avatar
Christoph Cullmann committed
69 70 71 72 73 74 75 76 77
}

bool KateProject::load (const QString &fileName)
{
  /**
   * bail out if already fileName set!
   */
  if (!m_fileName.isEmpty())
    return false;
Christoph Cullmann's avatar
Christoph Cullmann committed
78

Christoph Cullmann's avatar
Christoph Cullmann committed
79
  /**
80
   * set new filename and base directory
Christoph Cullmann's avatar
Christoph Cullmann committed
81 82
   */
  m_fileName = fileName;
83
  m_baseDir = QFileInfo(m_fileName).canonicalPath();
Christoph Cullmann's avatar
Christoph Cullmann committed
84

Christoph Cullmann's avatar
Christoph Cullmann committed
85 86 87 88 89 90
  /**
   * trigger reload
   */
  return reload ();
}

91
bool KateProject::reload (bool force)
Christoph Cullmann's avatar
Christoph Cullmann committed
92 93 94 95 96 97 98
{
  /**
   * open the file for reading, bail out on error!
   */
  QFile file (m_fileName);
  if (!file.open (QFile::ReadOnly))
    return false;
Christoph Cullmann's avatar
Christoph Cullmann committed
99

Christoph Cullmann's avatar
Christoph Cullmann committed
100 101 102 103 104 105 106 107
  /**
   * parse the whole file, bail out again on error!
   */
  bool ok = true;
  QJson::Parser parser;
  QVariant project = parser.parse (&file, &ok);
  if (!ok)
    return false;
Christoph Cullmann's avatar
Christoph Cullmann committed
108

Christoph Cullmann's avatar
Christoph Cullmann committed
109 110 111
  /**
   * now: get global group
   */
112
  QVariantMap globalProject = project.toMap ();
Christoph Cullmann's avatar
Christoph Cullmann committed
113

Christoph Cullmann's avatar
Christoph Cullmann committed
114 115 116
  /**
   * no name, bad => bail out
   */
117
  if (globalProject["name"].toString().isEmpty())
Christoph Cullmann's avatar
Christoph Cullmann committed
118
    return false;
119

120 121 122 123 124 125
  /**
   * support out-of-source project files
   */
  if (!globalProject["directory"].toString().isEmpty()) 
    m_baseDir = QFileInfo (globalProject["directory"].toString()).canonicalFilePath ();

126 127 128 129 130 131
  /**
   * anything changed?
   * else be done without forced reload!
   */
  if (!force && (m_projectMap == globalProject))
    return true;
Christoph Cullmann's avatar
Christoph Cullmann committed
132

Christoph Cullmann's avatar
Christoph Cullmann committed
133 134 135
  /**
   * setup global attributes in this object
   */
136
  m_projectMap = globalProject;
Christoph Cullmann's avatar
Christoph Cullmann committed
137

Christoph Cullmann's avatar
Christoph Cullmann committed
138
  /**
139
   * emit that we changed stuff
Christoph Cullmann's avatar
Christoph Cullmann committed
140
   */
141 142
  emit projectMapChanged ();

143
  /**
144
   * trigger worker to REALLY load the project model and stuff
145
   */
146
  QMetaObject::invokeMethod (m_worker, "loadProject", Qt::QueuedConnection, Q_ARG(QString, m_baseDir), Q_ARG(QVariantMap, m_projectMap));
Christoph Cullmann's avatar
Christoph Cullmann committed
147

148
  /**
Christoph Cullmann's avatar
Christoph Cullmann committed
149
   * done ok ;)
150
   */
Christoph Cullmann's avatar
Christoph Cullmann committed
151
  return true;
152 153
}

154
void KateProject::loadProjectDone (KateProjectSharedQStandardItem topLevel, KateProjectSharedQMapStringItem file2Item)
155
{
Christoph Cullmann's avatar
Christoph Cullmann committed
156
  /**
Christoph Cullmann's avatar
Christoph Cullmann committed
157
   * setup model data
Christoph Cullmann's avatar
Christoph Cullmann committed
158
   */
159
  m_model.clear ();
160
  m_model.invisibleRootItem()->appendColumn (topLevel->takeColumn (0));
161

162
  /**
Christoph Cullmann's avatar
Christoph Cullmann committed
163
   * setup file => item map
164
   */
165
  m_file2Item = file2Item;
166 167 168 169 170

  /**
   * model changed
   */
  emit modelChanged ();
Christoph Cullmann's avatar
Christoph Cullmann committed
171 172
}

173
void KateProject::loadIndexDone (KateProjectSharedProjectIndex projectIndex)
174 175
{
  /**
176
   * move to our project
177
   */
178
  m_projectIndex = projectIndex;
179 180 181 182 183

  /**
   * notify external world that data is available
   */
  emit indexChanged ();
184 185
}

186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213
QFile *KateProject::projectLocalFile (const QString &file) const
{
  /**
   * nothing on empty file names for project
   * should not happen
   */
  if (m_fileName.isEmpty())
    return 0;
  
  /**
   * create dir to store local files, else fail
   */
  if (!QDir().mkpath (m_fileName+".d"))
    return 0;
  
  /**
   * try to open file read-write
   */
  QFile *readWriteFile = new QFile (m_fileName + ".d" + QDir::separator() + file);
  if (!readWriteFile->open (QIODevice::ReadWrite)) {
    delete readWriteFile;
    return 0;
  }
  
  /**
   * all fine, return file
   */
  return readWriteFile;
214 215
}

Christoph Cullmann's avatar
Christoph Cullmann committed
216 217
QTextDocument* KateProject::notesDocument ()
{
218 219 220 221
  /**
   * already there?
   */
  if (m_notesDocument)
222
    return m_notesDocument;
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267
  
  /**
   * else create it
   */
  m_notesDocument = new QTextDocument (this);
  m_notesDocument->setDocumentLayout (new QPlainTextDocumentLayout (m_notesDocument));
  
  /**
   * and load text if possible
   */
  if (QFile *inFile = projectLocalFile ("notes.txt")) {
    {
      QTextStream inStream (inFile);
      inStream.setCodec ("UTF-8");
      m_notesDocument->setPlainText (inStream.readAll ());
    }
    delete inFile;
  }

  /**
   * and be done
   */
  return m_notesDocument;
}

void KateProject::saveNotesDocument ()
{
  /**
   * no notes document, nothing to do
   */
  if (!m_notesDocument)
    return;
  
  /**
   * try to get file to save to
   */
  if (QFile *outFile = projectLocalFile ("notes.txt")) {
    outFile->resize (0);
    {
      QTextStream outStream (outFile);
      outStream.setCodec ("UTF-8");
      outStream << m_notesDocument->toPlainText ();
    }
    delete outFile;
  }
268
}
269

Christoph Cullmann's avatar
Christoph Cullmann committed
270
// kate: space-indent on; indent-width 2; replace-tabs on;