~ubuntu-branches/ubuntu/vivid/kate/vivid-updates

« back to all changes in this revision

Viewing changes to kate/filetree/katefiletreemodel.cpp

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2014-12-04 16:49:41 UTC
  • mfrom: (1.6.6)
  • Revision ID: package-import@ubuntu.com-20141204164941-l3qbvsly83hhlw2v
Tags: 4:14.11.97-0ubuntu1
* New upstream release
* Update build-deps and use pkg-kde v3 for Qt 5 build
* kate-data now kate5-data for co-installability

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* This file is part of the KDE project
2
 
   Copyright (C) 2010 Thomas Fjellstrom <thomas@fjellstrom.ca>
3
 
 
4
 
   This library is free software; you can redistribute it and/or
5
 
   modify it under the terms of the GNU Library General Public
6
 
   License version 2 as published by the Free Software Foundation.
7
 
 
8
 
   This library is distributed in the hope that it will be useful,
9
 
   but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11
 
   Library General Public License for more details.
12
 
 
13
 
   You should have received a copy of the GNU Library General Public License
14
 
   along with this library; see the file COPYING.LIB.  If not, write to
15
 
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16
 
   Boston, MA 02110-1301, USA.
17
 
*/
18
 
 
19
 
#include "katefiletreemodel.h"
20
 
#include <KIcon>
21
 
#include <QDir>
22
 
#include <QFileInfo>
23
 
#include <QList>
24
 
#include <KMimeType>
25
 
#include <KColorScheme>
26
 
#include <KColorUtils>
27
 
#include <klocale.h>
28
 
 
29
 
#include <ktexteditor/document.h>
30
 
 
31
 
#include <kate/application.h>
32
 
#include <kate/documentmanager.h>
33
 
 
34
 
#include "katefiletreedebug.h"
35
 
 
36
 
class ProxyItemDir;
37
 
class ProxyItem {
38
 
  friend class KateFileTreeModel;
39
 
  
40
 
  public:
41
 
    enum Flag { None = 0, Dir = 1, Modified = 2, ModifiedExternally = 4, DeletedExternally = 8, Empty = 16, ShowFullPath = 32, Host=64 };
42
 
    Q_DECLARE_FLAGS(Flags, Flag)
43
 
    
44
 
    ProxyItem(QString n, ProxyItemDir *p = 0, Flags f = ProxyItem::None);
45
 
    ~ProxyItem();
46
 
 
47
 
    int addChild(ProxyItem *p);
48
 
    void remChild(ProxyItem *p);
49
 
 
50
 
    ProxyItemDir *parent();
51
 
 
52
 
    ProxyItem *child(int idx);
53
 
    int childCount();
54
 
 
55
 
    int row();
56
 
    
57
 
    QString display();
58
 
    QString path();
59
 
    QString documentName();
60
 
    void setPath(const QString &str);
61
 
    
62
 
    void setIcon(KIcon i);
63
 
    KIcon icon();
64
 
 
65
 
    QList<ProxyItem*> &children();
66
 
 
67
 
    void setDoc(KTextEditor::Document *doc);
68
 
    KTextEditor::Document *doc();
69
 
    QList<KTextEditor::Document*> docTree() const;
70
 
 
71
 
    void setFlags(Flags flags);
72
 
    void setFlag(Flag flag);
73
 
    void clearFlag(Flag flag);
74
 
    bool flag(Flag flag);
75
 
    void setHost(const QString &host);
76
 
    const QString& host() const;
77
 
    
78
 
  private:
79
 
    QString m_path;
80
 
    QString m_documentName;
81
 
    ProxyItemDir *m_parent;
82
 
    QList<ProxyItem*> m_children;
83
 
    int m_row;
84
 
    Flags m_flags;
85
 
    
86
 
    QString m_display;
87
 
    KIcon m_icon;
88
 
    KTextEditor::Document *m_doc;
89
 
    QString m_host;
90
 
  protected:
91
 
    void initDisplay();
92
 
};
93
 
 
94
 
QDebug operator<<(QDebug dbg, ProxyItem *item)
95
 
{
96
 
  if(!item) {
97
 
    dbg.nospace() << "ProxyItem(0x0) ";
98
 
    return dbg.maybeSpace();
99
 
  }
100
 
  
101
 
  void *parent = static_cast<void *>(item->parent());
102
 
  
103
 
  dbg.nospace() << "ProxyItem(" << (void*)item << ",";
104
 
  dbg.nospace() << parent << "," << item->row() << ",";
105
 
  dbg.nospace() << item->doc() << "," << item->path() << ") ";
106
 
  return dbg.maybeSpace();
107
 
}
108
 
 
109
 
 
110
 
class ProxyItemDir : public ProxyItem
111
 
{
112
 
  public:
113
 
    ProxyItemDir(QString n, ProxyItemDir *p = 0) : ProxyItem(n, p) { setFlag(ProxyItem::Dir); initDisplay();}
114
 
};
115
 
 
116
 
QDebug operator<<(QDebug dbg, ProxyItemDir *item)
117
 
{
118
 
  if(!item) {
119
 
    dbg.nospace() << "ProxyItemDir(0x0) ";
120
 
    return dbg.maybeSpace();
121
 
  }
122
 
  
123
 
  void *parent = static_cast<void *>(item->parent());
124
 
  
125
 
  dbg.nospace() << "ProxyItemDir(" << (void*)item << ",";
126
 
  dbg.nospace() << parent << "," << item->row() << ",";
127
 
  dbg.nospace() << item->path() << ", children:" << item->childCount() << ") ";
128
 
  return dbg.maybeSpace();
129
 
}
130
 
 
131
 
Q_DECLARE_OPERATORS_FOR_FLAGS(ProxyItem::Flags)
132
 
 
133
 
ProxyItem::ProxyItem(QString d, ProxyItemDir *p, ProxyItem::Flags f)
134
 
  : m_path(d), m_parent(p), m_row(-1), m_flags(f), m_doc(0)
135
 
{
136
 
  kDebug(debugArea()) << this;
137
 
  initDisplay();
138
 
  
139
 
  if(p)
140
 
    p->addChild(this);
141
 
 
142
 
}
143
 
 
144
 
ProxyItem::~ProxyItem()
145
 
{
146
 
  foreach(ProxyItem *item, m_children) {
147
 
    delete item;
148
 
  }
149
 
}
150
 
 
151
 
void ProxyItem::initDisplay()
152
 
{
153
 
  // triggers only if this is a top level node and the root has the show full path flag set.
154
 
  if (flag(ProxyItem::Dir) && m_parent && !m_parent->m_parent && m_parent->flag(ProxyItem::ShowFullPath)) {
155
 
    m_display = m_path;
156
 
    if(m_display.startsWith(QDir::homePath())) {
157
 
      m_display.replace(0, QDir::homePath().length(), "~");
158
 
    }
159
 
  } else {
160
 
    m_display = m_path.section(QLatin1Char('/'), -1, -1);
161
 
    if (flag(ProxyItem::Host) && (!m_parent || (m_parent && !m_parent->m_parent))) {
162
 
      QString hostPrefix="["+host()+"]";
163
 
      if (hostPrefix!=m_display)
164
 
        m_display=hostPrefix+m_display;
165
 
    }
166
 
  }
167
 
    
168
 
}
169
 
 
170
 
int ProxyItem::addChild(ProxyItem *item)
171
 
{
172
 
  int item_row = m_children.count();
173
 
  item->m_row = item_row;
174
 
  m_children.append(item);
175
 
  item->m_parent = static_cast<ProxyItemDir*>(this);
176
 
 
177
 
  item->initDisplay();
178
 
 
179
 
  kDebug(debugArea()) << "added" << item << "to" << item->m_parent;
180
 
  return item_row;
181
 
}
182
 
 
183
 
void ProxyItem::remChild(ProxyItem *item)
184
 
{
185
 
  kDebug(debugArea()) << "remove" << item << "from" << static_cast<ProxyItemDir*>(this);
186
 
  m_children.removeOne(item);
187
 
  // fix up item rows
188
 
  // could be done a little better, but this'll work.
189
 
  for(int i = 0; i < m_children.count(); i++) {
190
 
    m_children[i]->m_row = i;
191
 
  }
192
 
 
193
 
  item->m_parent = 0;
194
 
}
195
 
 
196
 
ProxyItemDir *ProxyItem::parent()
197
 
{
198
 
  return m_parent;
199
 
}
200
 
 
201
 
ProxyItem *ProxyItem::child(int idx)
202
 
{
203
 
  if(idx < 0 || idx >= m_children.count()) return 0;
204
 
  return m_children[idx];
205
 
}
206
 
 
207
 
int ProxyItem::childCount()
208
 
{
209
 
  return m_children.count();
210
 
}
211
 
 
212
 
int ProxyItem::row()
213
 
{
214
 
  return m_row;
215
 
}
216
 
 
217
 
KIcon ProxyItem::icon()
218
 
{
219
 
  if(m_children.count())
220
 
    return KIcon("folder");
221
 
 
222
 
  return m_icon;
223
 
}
224
 
 
225
 
void ProxyItem::setIcon(KIcon i)
226
 
{
227
 
  m_icon = i;
228
 
}
229
 
 
230
 
QString ProxyItem::documentName() {
231
 
  return m_documentName;
232
 
}
233
 
 
234
 
QString ProxyItem::display()
235
 
{
236
 
  return m_display;
237
 
}
238
 
 
239
 
QString ProxyItem::path()
240
 
{
241
 
  return m_path;
242
 
}
243
 
 
244
 
void ProxyItem::setPath(const QString &p)
245
 
{
246
 
  m_path = p;
247
 
  initDisplay();
248
 
}
249
 
 
250
 
QList<ProxyItem*> &ProxyItem::children()
251
 
{
252
 
  return m_children;
253
 
}
254
 
 
255
 
void ProxyItem::setDoc(KTextEditor::Document *doc)
256
 
{
257
 
  m_doc = doc;
258
 
  if (!doc)
259
 
    m_documentName=QString();
260
 
  else {
261
 
        QString docName=doc->documentName();
262
 
        if (flag(ProxyItem::Host))
263
 
          m_documentName="["+m_host+"]"+docName;
264
 
        else
265
 
          m_documentName=docName;
266
 
  }
267
 
}
268
 
 
269
 
KTextEditor::Document *ProxyItem::doc()
270
 
{
271
 
  return m_doc;
272
 
}
273
 
 
274
 
QList<KTextEditor::Document*> ProxyItem::docTree() const
275
 
{
276
 
  QList<KTextEditor::Document*> result;
277
 
  if (m_doc) {
278
 
    result.append(m_doc);
279
 
  }
280
 
  for (QList<ProxyItem*>::const_iterator iter = m_children.constBegin(); iter != m_children.constEnd(); ++iter) {
281
 
    result.append((*iter)->docTree());
282
 
  }
283
 
  return result;
284
 
}
285
 
 
286
 
bool ProxyItem::flag(Flag f)
287
 
{
288
 
  return m_flags & f;
289
 
}
290
 
 
291
 
void ProxyItem::setFlag(Flag f)
292
 
{
293
 
  m_flags |= f;
294
 
}
295
 
 
296
 
void ProxyItem::setFlags(Flags f)
297
 
{
298
 
  m_flags = f;
299
 
}
300
 
 
301
 
void ProxyItem::clearFlag(Flag f)
302
 
{
303
 
  m_flags &= ~f;
304
 
}
305
 
 
306
 
void ProxyItem::setHost(const QString& host) 
307
 
{
308
 
  QString docName;
309
 
  if (m_doc)
310
 
    docName=m_doc->documentName();
311
 
  if (host.isEmpty()) {
312
 
    clearFlag(Host);
313
 
    m_documentName=docName;
314
 
  } else {
315
 
    setFlag(Host);
316
 
    m_documentName="["+host+"]"+docName;
317
 
  }
318
 
  m_host=host;
319
 
  
320
 
  initDisplay();
321
 
}
322
 
 
323
 
const QString& ProxyItem::host() const
324
 
{
325
 
  return m_host;
326
 
}
327
 
 
328
 
KateFileTreeModel::KateFileTreeModel(QObject *p)
329
 
  : QAbstractItemModel(p),
330
 
    m_root(new ProxyItemDir(QString("m_root"), 0))
331
 
{
332
 
 
333
 
  // setup default settings
334
 
  // session init will set these all soon
335
 
  KColorScheme colors(QPalette::Active);
336
 
  QColor bg = colors.background().color();
337
 
  m_editShade = KColorUtils::tint(bg, colors.foreground(KColorScheme::ActiveText).color(), 0.5);
338
 
  m_viewShade = KColorUtils::tint(bg, colors.foreground(KColorScheme::VisitedText).color(), 0.5);
339
 
  m_shadingEnabled = true;
340
 
  m_listMode = false;
341
 
  
342
 
  initModel();
343
 
}
344
 
 
345
 
KateFileTreeModel::~KateFileTreeModel()
346
 
{
347
 
 
348
 
}
349
 
 
350
 
bool KateFileTreeModel::shadingEnabled()
351
 
{
352
 
  return m_shadingEnabled;
353
 
}
354
 
 
355
 
void KateFileTreeModel::setShadingEnabled(bool se)
356
 
{
357
 
  if(m_shadingEnabled != se) {
358
 
    updateBackgrounds(true);
359
 
    m_shadingEnabled = se;
360
 
  }
361
 
}
362
 
 
363
 
QColor KateFileTreeModel::editShade()
364
 
{
365
 
  return m_editShade;
366
 
}
367
 
 
368
 
void KateFileTreeModel::setEditShade(QColor es)
369
 
{
370
 
  m_editShade = es;
371
 
}
372
 
 
373
 
QColor KateFileTreeModel::viewShade()
374
 
{
375
 
  return m_viewShade;
376
 
}
377
 
 
378
 
void KateFileTreeModel::setViewShade(QColor vs)
379
 
{
380
 
  m_viewShade = vs;
381
 
}
382
 
 
383
 
bool KateFileTreeModel::showFullPathOnRoots(void)
384
 
{
385
 
  return m_root->flag(ProxyItem::ShowFullPath);
386
 
}
387
 
 
388
 
void KateFileTreeModel::setShowFullPathOnRoots(bool s)
389
 
{
390
 
  if(s)
391
 
    m_root->setFlag(ProxyItem::ShowFullPath);
392
 
  else
393
 
    m_root->clearFlag(ProxyItem::ShowFullPath);
394
 
  
395
 
  foreach(ProxyItem *root, m_root->children()) {
396
 
    root->initDisplay();
397
 
  }
398
 
}
399
 
 
400
 
// FIXME: optimize this later to insert all at once if possible
401
 
// maybe add a "bool emitSignals" to documentOpened
402
 
// and possibly use beginResetModel here? I dunno.
403
 
 
404
 
void KateFileTreeModel::initModel()
405
 
{
406
 
  // add already existing documents
407
 
  foreach( KTextEditor::Document* doc, Kate::application()->documentManager()->documents() )
408
 
    documentOpened( doc );
409
 
}
410
 
 
411
 
void KateFileTreeModel::clearModel()
412
 
{
413
 
  // remove all items
414
 
  // can safely ignore documentClosed here
415
 
 
416
 
  beginRemoveRows(QModelIndex(), 0, m_root->childCount()-1);
417
 
 
418
 
  delete m_root;
419
 
  m_root = new ProxyItemDir(QString("m_root"), 0);
420
 
 
421
 
  m_docmap.clear();
422
 
  m_viewHistory.clear();
423
 
  m_editHistory.clear();
424
 
  m_brushes.clear();
425
 
 
426
 
  endRemoveRows();
427
 
}
428
 
 
429
 
void KateFileTreeModel::connectDocument(const KTextEditor::Document *doc)
430
 
{
431
 
  connect(doc, SIGNAL(documentNameChanged(KTextEditor::Document*)), this, SLOT(documentNameChanged(KTextEditor::Document*)));
432
 
  connect(doc, SIGNAL(documentUrlChanged(KTextEditor::Document*)), this, SLOT(documentNameChanged(KTextEditor::Document*)));
433
 
  connect(doc, SIGNAL(modifiedChanged(KTextEditor::Document*)), this, SLOT(documentModifiedChanged(KTextEditor::Document*)));
434
 
  connect(doc, SIGNAL(modifiedOnDisk(KTextEditor::Document*,bool,KTextEditor::ModificationInterface::ModifiedOnDiskReason)),
435
 
          this,  SLOT(documentModifiedOnDisc(KTextEditor::Document*,bool,KTextEditor::ModificationInterface::ModifiedOnDiskReason)) );
436
 
}
437
 
 
438
 
QModelIndex KateFileTreeModel::docIndex(KTextEditor::Document *d)
439
 
{
440
 
  kDebug(debugArea()) << "BEGIN!";
441
 
  ProxyItem *item = m_docmap[d];
442
 
  if(!item) {
443
 
    kDebug(debugArea()) << "doc" << d << "does not exist";
444
 
    return QModelIndex();
445
 
  }
446
 
 
447
 
  kDebug(debugArea()) << "END!";
448
 
  return createIndex(item->row(), 0, item);
449
 
}
450
 
 
451
 
Qt::ItemFlags KateFileTreeModel::flags( const QModelIndex &index ) const
452
 
{
453
 
  Qt::ItemFlags flags = Qt::ItemIsEnabled;
454
 
 
455
 
  if(!index.isValid())
456
 
    return 0;
457
 
  
458
 
  ProxyItem *item = static_cast<ProxyItem*>(index.internalPointer());
459
 
  if(item && !item->childCount()) {
460
 
    flags |= Qt::ItemIsSelectable;
461
 
  }
462
 
  
463
 
  return flags;
464
 
}
465
 
 
466
 
#include "metatype_qlist_ktexteditor_document_pointer.h"
467
 
 
468
 
QVariant KateFileTreeModel::data( const QModelIndex &index, int role ) const
469
 
{
470
 
  //kDebug(debugArea()) << "BEGIN!";
471
 
  if(!index.isValid()) {
472
 
    kDebug(debugArea()) << "index is invalid!";
473
 
    return QVariant();
474
 
  }
475
 
 
476
 
  ProxyItem *item = static_cast<ProxyItem *>(index.internalPointer());
477
 
  if(!item) {
478
 
    kDebug(debugArea()) << "internal pointer is null!";
479
 
    return QVariant();
480
 
  }
481
 
  
482
 
  switch(role) {
483
 
    case KateFileTreeModel::PathRole:
484
 
      // allow to sort with hostname + path, bug 271488
485
 
      return (item->doc() && !item->doc()->url().isEmpty()) ? item->doc()->url().pathOrUrl() : item->path();
486
 
      
487
 
    case KateFileTreeModel::DocumentRole:
488
 
      return QVariant::fromValue(item->doc());
489
 
 
490
 
    case KateFileTreeModel::OpeningOrderRole:
491
 
      return item->row();
492
 
 
493
 
    case KateFileTreeModel::DocumentTreeRole:
494
 
      return QVariant::fromValue(item->docTree());
495
 
 
496
 
    case Qt::DisplayRole:
497
 
      // in list mode we want to use kate's fancy names.
498
 
      if(m_listMode) {
499
 
        return item->documentName();
500
 
      } else
501
 
        return item->display();
502
 
 
503
 
    case Qt::DecorationRole:
504
 
      return item->icon();
505
 
 
506
 
    case Qt::ToolTipRole: {
507
 
      QString tooltip = item->path();
508
 
      if (item->flag(ProxyItem::DeletedExternally) || item->flag(ProxyItem::ModifiedExternally)) {
509
 
        tooltip = i18nc("%1 is the full path", "<p><b>%1</b></p><p>The document has been modified by another application.</p>", item->path());
510
 
      }
511
 
 
512
 
      return tooltip;
513
 
    }
514
 
 
515
 
    case Qt::ForegroundRole: {
516
 
      KColorScheme colors(QPalette::Active);
517
 
      if(!item->flag(ProxyItem::Dir) && (!item->doc() || item->doc()->openingError())) return colors.foreground(KColorScheme::InactiveText).color();
518
 
    } break;
519
 
      
520
 
    case Qt::BackgroundRole:
521
 
      // TODO: do that funky shading the file list does...
522
 
      if(m_shadingEnabled && m_brushes.contains(item))
523
 
        return m_brushes[item];
524
 
      break;
525
 
  }
526
 
 
527
 
  //kDebug(debugArea()) << "END!";
528
 
  return QVariant();
529
 
}
530
 
 
531
 
QVariant KateFileTreeModel::headerData( int section, Qt::Orientation orientation, int role ) const
532
 
{
533
 
  Q_UNUSED(orientation);
534
 
  Q_UNUSED(role);
535
 
  
536
 
  if(section == 0)
537
 
    return QString("a header");
538
 
  
539
 
  return QVariant();
540
 
}
541
 
 
542
 
int KateFileTreeModel::rowCount( const QModelIndex &parent ) const
543
 
{
544
 
  if(!parent.isValid())
545
 
    return m_root->childCount();
546
 
 
547
 
  ProxyItem *item = static_cast<ProxyItem *>(parent.internalPointer());
548
 
  if(!item) {
549
 
    kDebug(debugArea()) << "internal pointer is invalid";
550
 
    return 0;
551
 
  }
552
 
 
553
 
  return item->childCount();
554
 
}
555
 
 
556
 
int KateFileTreeModel::columnCount( const QModelIndex &parent ) const
557
 
{
558
 
  Q_UNUSED(parent);
559
 
  return 1;
560
 
}
561
 
 
562
 
 
563
 
QModelIndex KateFileTreeModel::parent( const QModelIndex &index ) const
564
 
{
565
 
  if(!index.isValid()) {
566
 
    kDebug(debugArea()) << "index is invalid";
567
 
    return QModelIndex();
568
 
  }
569
 
  
570
 
  ProxyItem *item = static_cast<ProxyItem *>(index.internalPointer());
571
 
  if(!item) {
572
 
    kDebug(debugArea()) << "internal pointer is invalid";
573
 
    return QModelIndex();
574
 
  }
575
 
 
576
 
  if(!item->parent()) {
577
 
    kDebug(debugArea()) << "parent pointer is null";
578
 
    return QModelIndex();
579
 
  }
580
 
 
581
 
  if(item->parent() == m_root)
582
 
    return QModelIndex();
583
 
 
584
 
  return createIndex(item->parent()->row(), 0, item->parent());
585
 
}
586
 
 
587
 
QModelIndex KateFileTreeModel::index( int row, int column, const QModelIndex &parent ) const
588
 
{
589
 
  ProxyItem *p = 0;
590
 
  if(column != 0) {
591
 
    kDebug(debugArea()) << "column is invalid";
592
 
    return QModelIndex();
593
 
  }
594
 
  
595
 
  if(!parent.isValid())
596
 
    p = m_root;
597
 
  else
598
 
    p = static_cast<ProxyItem *>(parent.internalPointer());
599
 
 
600
 
  if(!p) {
601
 
    kDebug(debugArea()) << "internal pointer is invalid";
602
 
    return QModelIndex();
603
 
  }
604
 
  
605
 
  if(row < 0 || row >= p->childCount()) {
606
 
    kDebug(debugArea()) << "row is out of bounds (" << row << " < 0 || " << row << " >= " << p->childCount() << ")";
607
 
    return QModelIndex();
608
 
  }
609
 
 
610
 
  return createIndex(row, 0, p->child(row));
611
 
}
612
 
 
613
 
bool KateFileTreeModel::hasChildren( const QModelIndex & parent ) const
614
 
{
615
 
  if(!parent.isValid())
616
 
    return m_root->childCount() > 0;
617
 
 
618
 
  ProxyItem *item = static_cast<ProxyItem*>(parent.internalPointer());
619
 
  if(!item) {
620
 
    kDebug(debugArea()) << "internal pointer is null";
621
 
    return false;
622
 
  }
623
 
  
624
 
  return item->childCount() > 0;
625
 
}
626
 
 
627
 
bool KateFileTreeModel::isDir(const QModelIndex &index)
628
 
{
629
 
  if(!index.isValid())
630
 
    return true;
631
 
  
632
 
  ProxyItem *item = static_cast<ProxyItem*>(index.internalPointer());
633
 
  if(!item) {
634
 
    kDebug(debugArea()) << "internal pointer is null";
635
 
    return false;
636
 
  }
637
 
  
638
 
  return item->flag(ProxyItem::Dir);
639
 
}
640
 
 
641
 
bool KateFileTreeModel::listMode()
642
 
{
643
 
  return m_listMode;
644
 
}
645
 
 
646
 
void KateFileTreeModel::setListMode(bool lm)
647
 
{
648
 
  if(lm != m_listMode) {
649
 
    m_listMode = lm;
650
 
 
651
 
    clearModel();
652
 
    initModel();
653
 
  }
654
 
}
655
 
 
656
 
void KateFileTreeModel::documentOpened(KTextEditor::Document *doc)
657
 
{
658
 
  QString path = doc->url().path();
659
 
  bool isEmpty = false;
660
 
  QString host;
661
 
  
662
 
  if(doc->url().isEmpty()) {
663
 
    path = doc->documentName();
664
 
    isEmpty = true;
665
 
  } else {
666
 
    host=doc->url().host();
667
 
    if (!host.isEmpty())
668
 
      path="["+host+"]"+path;  
669
 
    
670
 
  }
671
 
  
672
 
  ProxyItem *item = new ProxyItem(path, 0);
673
 
  
674
 
  if(isEmpty)
675
 
    item->setFlag(ProxyItem::Empty);
676
 
  
677
 
  m_debugmap[item] = item;
678
 
  
679
 
  item->setDoc(doc);
680
 
  item->setHost(host);
681
 
  kDebug(debugArea()) << "before add:" << item;
682
 
  setupIcon(item);
683
 
  handleInsert(item);
684
 
  m_docmap[doc] = item;
685
 
  connectDocument(doc);
686
 
 
687
 
  kDebug(debugArea()) << "after add:" << item;
688
 
  
689
 
}
690
 
 
691
 
void KateFileTreeModel::documentsOpened(const QList<KTextEditor::Document*> &docs)
692
 
{
693
 
  foreach(KTextEditor::Document *doc, docs) {
694
 
    if (m_docmap.contains(doc)) {
695
 
      documentNameChanged(doc);
696
 
    } else {
697
 
      documentOpened(doc);
698
 
    }
699
 
  }
700
 
}
701
 
 
702
 
void KateFileTreeModel::documentModifiedChanged(KTextEditor::Document *doc)
703
 
{
704
 
  kDebug(debugArea()) << "BEGIN!";
705
 
  
706
 
  ProxyItem *item = m_docmap[doc];
707
 
  if(!item)
708
 
    return;
709
 
 
710
 
  if(doc->isModified()) {
711
 
    item->setFlag(ProxyItem::Modified);
712
 
    kDebug(debugArea()) << "modified!";
713
 
  }
714
 
  else {
715
 
    item->clearFlag(ProxyItem::Modified);
716
 
    item->clearFlag(ProxyItem::ModifiedExternally);
717
 
    item->clearFlag(ProxyItem::DeletedExternally);
718
 
    kDebug(debugArea()) << "saved!";
719
 
  }
720
 
 
721
 
  setupIcon(item);
722
 
  
723
 
  QModelIndex idx = createIndex(item->row(), 0, item);
724
 
  emit dataChanged(idx, idx);
725
 
 
726
 
  kDebug(debugArea()) << "END!";
727
 
}
728
 
 
729
 
void KateFileTreeModel::documentModifiedOnDisc(KTextEditor::Document *doc, bool modified, KTextEditor::ModificationInterface::ModifiedOnDiskReason reason )
730
 
{
731
 
  Q_UNUSED(modified);
732
 
  kDebug(debugArea()) << "BEGIN!";
733
 
  ProxyItem *item = m_docmap[doc];
734
 
  if(!item)
735
 
    return;
736
 
 
737
 
  // This didn't do what I thought it did, on an ignore
738
 
  // we'd get !modified causing the warning icons to disappear
739
 
  if(!modified) {
740
 
    item->clearFlag(ProxyItem::ModifiedExternally);
741
 
    item->clearFlag(ProxyItem::DeletedExternally);
742
 
  } else {
743
 
    if(reason == KTextEditor::ModificationInterface::OnDiskDeleted) {
744
 
      item->setFlag(ProxyItem::DeletedExternally);
745
 
      kDebug(debugArea()) << "deleted!";
746
 
    }
747
 
    else if(reason == KTextEditor::ModificationInterface::OnDiskModified) {
748
 
      item->setFlag(ProxyItem::ModifiedExternally);
749
 
      kDebug(debugArea()) << "modified!";
750
 
    }
751
 
    else if(reason == KTextEditor::ModificationInterface::OnDiskCreated) {
752
 
      kDebug(debugArea()) << "created!";
753
 
      // with out this, on "reload" we don't get the icons removed :(
754
 
      item->clearFlag(ProxyItem::ModifiedExternally);
755
 
      item->clearFlag(ProxyItem::DeletedExternally);
756
 
    }
757
 
  }
758
 
  
759
 
  setupIcon(item);
760
 
  
761
 
  QModelIndex idx = createIndex(item->row(), 0, item);
762
 
  emit dataChanged(idx, idx);
763
 
  kDebug(debugArea()) << "END!";
764
 
}
765
 
 
766
 
void KateFileTreeModel::documentActivated(KTextEditor::Document *doc)
767
 
{
768
 
  kDebug(debugArea()) << "BEGIN!";
769
 
 
770
 
  if(!m_docmap.contains(doc)) {
771
 
    kDebug(debugArea()) << "invalid doc" << doc;
772
 
    return;
773
 
  }
774
 
 
775
 
  ProxyItem *item = m_docmap[doc];
776
 
  kDebug(debugArea()) << "adding viewHistory" << item;
777
 
  m_viewHistory.removeAll(item);
778
 
  m_viewHistory.prepend(item);
779
 
 
780
 
  while (m_viewHistory.count() > 10) m_viewHistory.removeLast();
781
 
 
782
 
  updateBackgrounds();
783
 
  
784
 
  kDebug(debugArea()) << "END!";
785
 
}
786
 
 
787
 
void KateFileTreeModel::documentEdited(KTextEditor::Document *doc)
788
 
{
789
 
  kDebug(debugArea()) << "BEGIN!";
790
 
 
791
 
  if(!m_docmap.contains(doc)) {
792
 
    kDebug(debugArea()) << "invalid doc" << doc;
793
 
    return;
794
 
  }
795
 
 
796
 
  ProxyItem *item = m_docmap[doc];
797
 
  kDebug(debugArea()) << "adding editHistory" << item;
798
 
  m_editHistory.removeAll(item);
799
 
  m_editHistory.prepend(item);
800
 
  while (m_editHistory.count() > 10) m_editHistory.removeLast();
801
 
 
802
 
  updateBackgrounds();
803
 
  
804
 
  kDebug(debugArea()) << "END!";
805
 
}
806
 
 
807
 
void KateFileTreeModel::slotAboutToDeleteDocuments(const QList<KTextEditor::Document*> &docs)
808
 
{
809
 
  foreach (const KTextEditor::Document *doc, docs) {
810
 
    disconnect(doc, SIGNAL(documentNameChanged(KTextEditor::Document*)), this, SLOT(documentNameChanged(KTextEditor::Document*)));
811
 
    disconnect(doc, SIGNAL(documentUrlChanged(KTextEditor::Document*)), this, SLOT(documentNameChanged(KTextEditor::Document*)));
812
 
    disconnect(doc, SIGNAL(modifiedChanged(KTextEditor::Document*)), this, SLOT(documentModifiedChanged(KTextEditor::Document*)));
813
 
    disconnect(doc, SIGNAL(modifiedOnDisk(KTextEditor::Document*,bool,KTextEditor::ModificationInterface::ModifiedOnDiskReason)),
814
 
               this,  SLOT(documentModifiedOnDisc(KTextEditor::Document*,bool,KTextEditor::ModificationInterface::ModifiedOnDiskReason)) );
815
 
  }
816
 
}
817
 
 
818
 
void KateFileTreeModel::slotDocumentsDeleted(const QList<KTextEditor::Document*> &docs)
819
 
{
820
 
  foreach (const KTextEditor::Document *doc, docs) {
821
 
    connectDocument(doc);
822
 
  }
823
 
}
824
 
 
825
 
class EditViewCount
826
 
{
827
 
  public:
828
 
    EditViewCount(): edit(0), view(0)
829
 
    {}
830
 
    int edit;
831
 
    int view;
832
 
};
833
 
 
834
 
void KateFileTreeModel::updateBackgrounds(bool force)
835
 
{
836
 
  if (!m_shadingEnabled && !force) return;
837
 
  
838
 
  kDebug(debugArea()) << "BEGIN!";
839
 
  
840
 
  QMap <ProxyItem *, EditViewCount> helper;
841
 
  int i = 1;
842
 
  
843
 
  foreach (ProxyItem *item, m_viewHistory)
844
 
  {
845
 
    helper[item].view = i;
846
 
    if(!m_debugmap.contains(item)) {
847
 
      kDebug(debugArea()) << "m_viewHistory contains an item that doesn't exist?" << item;
848
 
    }
849
 
    i++;
850
 
  }
851
 
  
852
 
  i = 1;
853
 
  foreach (ProxyItem *item, m_editHistory)
854
 
  {
855
 
    helper[item].edit = i;
856
 
    if(!m_debugmap.contains(item)) {
857
 
      kDebug(debugArea()) << "m_editHistory contains an item that doesn't exist?" << item;
858
 
    }
859
 
    i++;
860
 
  }
861
 
  
862
 
  kDebug(debugArea()) << "m_editHistory contains " << m_editHistory.count()<<" elements";
863
 
        
864
 
  QMap<ProxyItem *, QBrush> oldBrushes = m_brushes;
865
 
  m_brushes.clear();
866
 
  
867
 
  int hc = m_viewHistory.count();
868
 
  int ec = m_editHistory.count();
869
 
  
870
 
  for (QMap<ProxyItem *, EditViewCount>::iterator it = helper.begin();it != helper.end();++it)
871
 
  {
872
 
    QColor shade( m_viewShade );
873
 
    QColor eshade( m_editShade );
874
 
    
875
 
    if (it.value().edit > 0)
876
 
    {
877
 
      int v = hc - it.value().view;
878
 
      int e = ec - it.value().edit + 1;
879
 
      
880
 
      e = e * e;
881
 
 
882
 
      int n = qMax(v + e, 1);
883
 
      
884
 
      shade.setRgb(
885
 
        ((shade.red()*v) + (eshade.red()*e)) / n,
886
 
        ((shade.green()*v) + (eshade.green()*e)) / n,
887
 
        ((shade.blue()*v) + (eshade.blue()*e)) / n
888
 
      );
889
 
    }
890
 
 
891
 
    // blend in the shade color; latest is most colored.
892
 
    double t = double(hc - it.value().view + 1) / double(hc);
893
 
 
894
 
    m_brushes[it.key()] = QBrush(KColorUtils::mix(QPalette().color(QPalette::Base), shade, t));
895
 
//     kdDebug()<<"m_brushes[it.key()]"<<it.key()<<m_brushes[it.key()];
896
 
  }
897
 
 
898
 
  foreach(ProxyItem *item, m_brushes.keys())
899
 
  {
900
 
    oldBrushes.remove(item);
901
 
    QModelIndex idx = createIndex(item->row(), 0, item);
902
 
    dataChanged(idx, idx);
903
 
  }
904
 
  
905
 
  foreach(ProxyItem *item, oldBrushes.keys())
906
 
  {
907
 
    QModelIndex idx = createIndex(item->row(), 0, item);
908
 
    dataChanged(idx, idx);
909
 
  }
910
 
 
911
 
  kDebug(debugArea()) << "END!";
912
 
}
913
 
 
914
 
void KateFileTreeModel::handleEmptyParents(ProxyItemDir *item)
915
 
{
916
 
  kDebug(debugArea()) << "BEGIN!";
917
 
  Q_ASSERT(item != 0);
918
 
  
919
 
  if(!item || !item->parent()) {
920
 
    kDebug(debugArea()) << "parent" << item << "grandparent" << (item ? item->parent() : 0);
921
 
    return;
922
 
  }
923
 
  
924
 
  ProxyItemDir *parent = item->parent();
925
 
  //emit layoutAboutToBeChanged();
926
 
  
927
 
  kDebug(debugArea()) << "item" << item << "parent" << parent;
928
 
  while(parent) {
929
 
    
930
 
    kDebug(debugArea()) << "item" << item << "parent" << parent;
931
 
    if(!item->childCount()) {
932
 
      QModelIndex parent_index = parent == m_root ? QModelIndex() : createIndex(parent->row(), 0, parent);
933
 
      beginRemoveRows(parent_index, item->row(), item->row());
934
 
      parent->remChild(item);
935
 
      endRemoveRows();
936
 
      kDebug(debugArea()) << "deleted" << item;
937
 
      delete item;
938
 
    }
939
 
    else {
940
 
      // breakout early, if this node isn't empty, theres no use in checking its parents
941
 
      kDebug(debugArea()) << "END!";
942
 
      return;
943
 
    }
944
 
    
945
 
    item = parent;
946
 
    parent = item->parent();
947
 
  }
948
 
  
949
 
  //emit layoutChanged();
950
 
  kDebug(debugArea()) << "END!";
951
 
}
952
 
 
953
 
void KateFileTreeModel::documentClosed(KTextEditor::Document *doc)
954
 
{
955
 
  QString path = doc->url().path();
956
 
  
957
 
  if(!m_docmap.contains(doc)) {
958
 
    kDebug(debugArea()) << "docmap doesn't contain doc" << doc;
959
 
    return;
960
 
  }
961
 
  
962
 
  kDebug(debugArea()) << path << m_docmap[doc];
963
 
 
964
 
  if(m_shadingEnabled) {
965
 
    ProxyItem *toRemove = m_docmap[doc];
966
 
    if(m_brushes.contains(toRemove)) {
967
 
      m_brushes.remove(toRemove);
968
 
      kDebug(debugArea()) << "removing brush" << toRemove;
969
 
    }
970
 
 
971
 
    if(m_viewHistory.contains(toRemove)) {
972
 
      m_viewHistory.removeAll(toRemove);
973
 
      kDebug(debugArea()) << "removing viewHistory" << toRemove;
974
 
    }
975
 
 
976
 
    if(m_editHistory.contains(toRemove)) {
977
 
      m_editHistory.removeAll(toRemove);
978
 
      kDebug(debugArea()) << "removing editHistory" << toRemove;
979
 
    }
980
 
  }
981
 
 
982
 
  ProxyItem *node = m_docmap[doc];
983
 
  ProxyItemDir *parent = node->parent();
984
 
  
985
 
  QModelIndex parent_index = parent == m_root ? QModelIndex() : createIndex(parent->row(), 0, parent);
986
 
  beginRemoveRows(parent_index, node->row(), node->row());
987
 
    node->parent()->remChild(node);
988
 
  endRemoveRows();
989
 
 
990
 
  m_debugmap.remove(node);
991
 
  
992
 
  delete node;
993
 
  handleEmptyParents(parent);
994
 
  
995
 
  m_docmap.remove(doc);
996
 
}
997
 
 
998
 
void KateFileTreeModel::documentNameChanged(KTextEditor::Document *doc)
999
 
{
1000
 
  kDebug(debugArea()) << "BEGIN!";
1001
 
 
1002
 
  if(!m_docmap.contains(doc)) {
1003
 
    kDebug(debugArea()) << "docmap doesn't contain doc" << doc;
1004
 
    return;
1005
 
  }
1006
 
  
1007
 
  ProxyItem *item = m_docmap[doc];
1008
 
  QString path = doc->url().path();
1009
 
  QString host;
1010
 
  if(doc->url().isEmpty()) {
1011
 
    kDebug(debugArea()) << "change to unnamed item";
1012
 
    path = doc->documentName();
1013
 
    item->setFlag(ProxyItem::Empty);
1014
 
  }
1015
 
  else {
1016
 
    item->clearFlag(ProxyItem::Empty);
1017
 
    host=doc->url().host();
1018
 
    if (!host.isEmpty())
1019
 
      path="["+host+"]"+path;
1020
 
  }
1021
 
 
1022
 
  kDebug(debugArea()) << item;
1023
 
  kDebug(debugArea()) << item->display() << "->" << path;
1024
 
 
1025
 
  
1026
 
  if(m_shadingEnabled) {
1027
 
    ProxyItem *toRemove = m_docmap[doc];
1028
 
    if(m_brushes.contains(toRemove)) {
1029
 
      QBrush brush=m_brushes[toRemove];
1030
 
      m_brushes.remove(toRemove);
1031
 
      m_brushes.insert(item,brush);
1032
 
      kDebug(debugArea()) << "removing brush" << toRemove;
1033
 
    }
1034
 
 
1035
 
    if(m_viewHistory.contains(toRemove)) {
1036
 
      int idx=m_viewHistory.indexOf(toRemove);
1037
 
      if (idx!=-1)
1038
 
        m_viewHistory.replace(idx,item);
1039
 
      kDebug(debugArea()) << "removing/replacing view history" << toRemove;
1040
 
    }
1041
 
 
1042
 
    if(m_editHistory.contains(toRemove)) {
1043
 
      int idx=m_editHistory.indexOf(toRemove);
1044
 
      if (idx!=-1)
1045
 
        m_editHistory.replace(idx,item);
1046
 
      kDebug(debugArea()) << "removing/replacing edit history" << toRemove;
1047
 
    }
1048
 
  }
1049
 
  
1050
 
  handleNameChange(item, path, host);
1051
 
  
1052
 
  triggerViewChangeAfterNameChange();
1053
 
  
1054
 
  kDebug(debugArea()) << "END!";
1055
 
}
1056
 
 
1057
 
ProxyItemDir *KateFileTreeModel::findRootNode(const QString &name, int r)
1058
 
{
1059
 
  QString base = name.section(QLatin1Char('/'), 0, -2);
1060
 
  foreach(ProxyItem *item, m_root->children()) {
1061
 
    QString path = item->path().section(QLatin1Char('/'), 0, -r);
1062
 
    if (!item->flag(ProxyItem::Host) && !QFileInfo(path).isAbsolute()) {
1063
 
      continue;
1064
 
    }
1065
 
 
1066
 
    // make sure we're actually matching against the right dir,
1067
 
    // previously the check below would match /foo/xy against /foo/x
1068
 
    // and return /foo/x rather than /foo/xy
1069
 
    // this seems a bit hackish, but is the simplest way to solve the
1070
 
    // current issue.
1071
 
    path += QLatin1Char('/');
1072
 
 
1073
 
    if(name.startsWith(path) && item->flag(ProxyItem::Dir)) {
1074
 
      return static_cast<ProxyItemDir*>(item);
1075
 
    }
1076
 
  }
1077
 
 
1078
 
  return 0;
1079
 
}
1080
 
 
1081
 
ProxyItemDir *KateFileTreeModel::findChildNode(ProxyItemDir *parent, const QString &name)
1082
 
{
1083
 
  Q_ASSERT(parent != 0);
1084
 
  
1085
 
  if(!parent || !parent->childCount()) {
1086
 
    kDebug(debugArea()) << "invalid parent or no children" << parent;
1087
 
    return 0;
1088
 
  }
1089
 
 
1090
 
  foreach(ProxyItem *item, parent->children()) {
1091
 
    if(item->display() == name) {
1092
 
      if(!item->flag(ProxyItem::Dir)) {
1093
 
        kDebug(debugArea()) << "found" << item << "but its not a dir?";
1094
 
        return 0;
1095
 
      }
1096
 
      
1097
 
      kDebug(debugArea()) << "found" << item;
1098
 
      return static_cast<ProxyItemDir*>(item);
1099
 
    }
1100
 
  }
1101
 
 
1102
 
  kDebug(debugArea()) << "!found:" << name;
1103
 
  return 0;
1104
 
}
1105
 
 
1106
 
void KateFileTreeModel::insertItemInto(ProxyItemDir *root, ProxyItem *item)
1107
 
{
1108
 
  kDebug(debugArea()) << "BEGIN!";
1109
 
 
1110
 
  Q_ASSERT(root != 0);
1111
 
  Q_ASSERT(item != 0);
1112
 
  
1113
 
  QString sep;
1114
 
  QString tail = item->path();
1115
 
  tail.remove(0, root->path().length());
1116
 
  QStringList parts = tail.split(QLatin1Char('/'), QString::SkipEmptyParts);
1117
 
  ProxyItemDir *ptr = root;
1118
 
  QStringList current_parts;
1119
 
  current_parts.append(root->path());
1120
 
 
1121
 
  // seems this can be empty, see bug 286191
1122
 
  if (!parts.isEmpty())
1123
 
    parts.pop_back();
1124
 
 
1125
 
  kDebug(debugArea()) << "creating tree for" << item;
1126
 
  foreach(const QString &part, parts) {
1127
 
    current_parts.append(part);
1128
 
    ProxyItemDir *find = findChildNode(ptr, part);
1129
 
    if(!find) {
1130
 
      QString new_name = current_parts.join(QLatin1String("/"));
1131
 
      QModelIndex parent_index = createIndex(ptr->row(), 0, ptr);
1132
 
      kDebug(debugArea()) << "adding" << part << "to" << ptr;
1133
 
      beginInsertRows(ptr == m_root ? QModelIndex() : parent_index, ptr->childCount(), ptr->childCount());
1134
 
      ptr = new ProxyItemDir(new_name, ptr);
1135
 
      endInsertRows();
1136
 
    }
1137
 
    else {
1138
 
        ptr = find;
1139
 
    }
1140
 
  }
1141
 
 
1142
 
  kDebug(debugArea()) << "adding" << item << "to" << ptr;
1143
 
  QModelIndex parent_index = createIndex(ptr->row(), 0, ptr);
1144
 
  beginInsertRows(ptr == m_root ? QModelIndex() : parent_index, ptr->childCount(), ptr->childCount());
1145
 
    ptr->addChild(item);
1146
 
  endInsertRows();
1147
 
 
1148
 
  kDebug(debugArea()) << "END!";
1149
 
}
1150
 
 
1151
 
void KateFileTreeModel::handleInsert(ProxyItem *item)
1152
 
{
1153
 
  kDebug(debugArea()) << "BEGIN!";
1154
 
 
1155
 
  Q_ASSERT(item != 0);
1156
 
  
1157
 
  if(m_listMode) {
1158
 
    kDebug(debugArea()) << "list mode, inserting into m_root";
1159
 
    beginInsertRows(QModelIndex(), m_root->childCount(), m_root->childCount());
1160
 
    m_root->addChild(item);
1161
 
    endInsertRows();
1162
 
    return;
1163
 
  }
1164
 
  
1165
 
  if(item->flag(ProxyItem::Empty)) {
1166
 
    kDebug(debugArea()) << "empty item";
1167
 
    beginInsertRows(QModelIndex(), m_root->childCount(), m_root->childCount());
1168
 
    m_root->addChild(item);
1169
 
    endInsertRows();
1170
 
    return;
1171
 
  }
1172
 
  
1173
 
  ProxyItemDir *root = findRootNode(item->path());
1174
 
  if(root) {
1175
 
    kDebug(debugArea()) << "got a root, inserting into it";
1176
 
    insertItemInto(root, item);
1177
 
  } else {
1178
 
    kDebug(debugArea()) << "creating a new root";
1179
 
 
1180
 
    // trim off trailing file and dir
1181
 
    QString base = item->path().section(QLatin1Char('/'), 0, -2);
1182
 
 
1183
 
    // create new root
1184
 
    ProxyItemDir *new_root = new ProxyItemDir(base, 0);
1185
 
    new_root->setHost(item->host());
1186
 
    
1187
 
    // add new root to m_root
1188
 
    kDebug(debugArea()) << "add" << new_root << "to m_root";
1189
 
    beginInsertRows(QModelIndex(), m_root->childCount(), m_root->childCount());
1190
 
      m_root->addChild(new_root);
1191
 
    endInsertRows();
1192
 
    
1193
 
    // same fix as in findRootNode, try to match a full dir, instead of a partial path
1194
 
    base += QLatin1Char('/');
1195
 
    
1196
 
    // try and merge existing roots with the new root node.
1197
 
    kDebug(debugArea()) << "attempting to merge some existing roots";
1198
 
    foreach(ProxyItem *root, m_root->children()) {
1199
 
      if(root == new_root || !root->flag(ProxyItem::Dir))
1200
 
        continue;
1201
 
      
1202
 
      if(root->path().startsWith(base)) {
1203
 
        kDebug(debugArea()) << "removing" << root << "from m_root";
1204
 
        beginRemoveRows(QModelIndex(), root->row(), root->row());
1205
 
          m_root->remChild(root);
1206
 
        endRemoveRows();
1207
 
 
1208
 
        kDebug(debugArea()) << "adding" << root << "to" << new_root;
1209
 
        //beginInsertRows(new_root_index, new_root->childCount(), new_root->childCount());
1210
 
          // this can't use new_root->addChild directly, or it'll potentially miss a bunch of subdirs
1211
 
          insertItemInto(new_root, root);
1212
 
        //endInsertRows();
1213
 
      }
1214
 
    }
1215
 
 
1216
 
    // add item to new root
1217
 
    kDebug(debugArea()) << "adding" << item << "to" << new_root;
1218
 
    // have to call begin/endInsertRows here, or the new item won't show up.
1219
 
    QModelIndex new_root_index = createIndex(new_root->row(), 0, new_root);
1220
 
    beginInsertRows(new_root_index, new_root->childCount(), new_root->childCount());
1221
 
      new_root->addChild(item);
1222
 
    endInsertRows();
1223
 
 
1224
 
  }
1225
 
 
1226
 
  kDebug(debugArea()) << "END!";
1227
 
}
1228
 
 
1229
 
void KateFileTreeModel::handleNameChange(ProxyItem *item, const QString &new_name, const QString& new_host)
1230
 
{
1231
 
  kDebug(debugArea()) << "BEGIN!";
1232
 
 
1233
 
  Q_ASSERT(item != 0);
1234
 
  
1235
 
  if(m_listMode) {
1236
 
    item->setPath(new_name);
1237
 
    item->setHost(new_host);
1238
 
    QModelIndex idx = createIndex(item->row(), 0, item);
1239
 
    setupIcon(item);
1240
 
    emit dataChanged(idx, idx);
1241
 
    kDebug(debugArea()) << "list mode, short circuit";
1242
 
    return;
1243
 
  }
1244
 
  
1245
 
  // for some reason we get useless name changes
1246
 
  if(item->path() == new_name) {
1247
 
    kDebug(debugArea()) << "bogus name change";
1248
 
    return;
1249
 
  }
1250
 
  
1251
 
  // in either case (new/change) we want to remove the item from its parent
1252
 
 
1253
 
  ProxyItemDir *parent = item->parent();
1254
 
  if(!parent) {
1255
 
    item->setPath(new_name);
1256
 
    item->setHost(new_host);
1257
 
    kDebug(debugArea()) << "ERROR: item" << item << "does not have a parent?";
1258
 
    return;
1259
 
  }
1260
 
 
1261
 
  item->setPath(new_name);
1262
 
  item->setHost(new_host);
1263
 
 
1264
 
  kDebug(debugArea()) << "removing" << item << "from" << parent;
1265
 
  QModelIndex parent_index = parent == m_root ? QModelIndex() : createIndex(parent->row(), 0, parent);
1266
 
  beginRemoveRows(parent_index, item->row(), item->row());
1267
 
    parent->remChild(item);
1268
 
  endRemoveRows();
1269
 
  
1270
 
  // remove empty parent nodes here, recursively.
1271
 
  handleEmptyParents(parent);
1272
 
  
1273
 
  // set new path
1274
 
  //item->setPath(new_name);
1275
 
 
1276
 
  // clear all but Empty flag
1277
 
  if(item->flag(ProxyItem::Empty))
1278
 
    item->setFlags(ProxyItem::Empty);
1279
 
  else
1280
 
    item->setFlags(ProxyItem::None);
1281
 
  
1282
 
  setupIcon(item);
1283
 
  
1284
 
  // new item
1285
 
  kDebug(debugArea()) << "inserting" << item;
1286
 
  handleInsert(item);
1287
 
 
1288
 
  kDebug(debugArea()) << "END!";
1289
 
}
1290
 
 
1291
 
void KateFileTreeModel::setupIcon(ProxyItem *item)
1292
 
{
1293
 
  kDebug(debugArea()) << "BEGIN!";
1294
 
 
1295
 
  Q_ASSERT(item != 0);
1296
 
  
1297
 
  QStringList emblems;
1298
 
  QString icon_name;
1299
 
  
1300
 
  if(item->flag(ProxyItem::Modified)) {
1301
 
    icon_name = "document-save";
1302
 
  }
1303
 
  else {
1304
 
    KUrl url = item->path();
1305
 
    icon_name = KMimeType::findByUrl(url, 0, true, true)->iconName();
1306
 
  }
1307
 
  
1308
 
  if(item->flag(ProxyItem::ModifiedExternally) || item->flag(ProxyItem::DeletedExternally)) {
1309
 
    emblems << "emblem-important";
1310
 
    kDebug(debugArea()) << "modified!";
1311
 
  }
1312
 
 
1313
 
  item->setIcon(KIcon(icon_name, 0, emblems));
1314
 
 
1315
 
  kDebug(debugArea()) << "END!";
1316
 
}
1317
 
 
1318
 
// kate: space-indent on; indent-width 2; replace-tabs on; mixed-indent off;