1 /*****************************************************************************
2  * Copyright (C) 2004 Shie Erlich <erlich@users.sourceforge.net>             *
3  * Copyright (C) 2004 Rafi Yanai <yanai@users.sourceforge.net>               *
4  * Copyright (C) 2010 Jan Lepper <dehtris@yahoo.de>                          *
5  * Copyright (C) 2004-2019 Krusader Krew [https://krusader.org]              *
6  *                                                                           *
7  * This file is part of Krusader [https://krusader.org].                     *
8  *                                                                           *
9  * Krusader is free software: you can redistribute it and/or modify          *
10  * it under the terms of the GNU General Public License as published by      *
11  * the Free Software Foundation, either version 2 of the License, or         *
12  * (at your option) any later version.                                       *
13  *                                                                           *
14  * Krusader is distributed in the hope that it will be useful,               *
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
17  * GNU General Public License for more details.                              *
18  *                                                                           *
19  * You should have received a copy of the GNU General Public License         *
20  * along with Krusader.  If not, see [http://www.gnu.org/licenses/].         *
21  *****************************************************************************/
22 
23 #include "dirhistoryqueue.h"
24 
25 #include "krpanel.h"
26 #include "PanelView/krview.h"
27 #include "../defaults.h"
28 #include "../krservices.h"
29 
30 // QtCore
31 #include <QDir>
32 
DirHistoryQueue(KrPanel * panel)33 DirHistoryQueue::DirHistoryQueue(KrPanel *panel) :
34     _panel(panel), _currentPos(0)
35 {
36 }
37 
~DirHistoryQueue()38 DirHistoryQueue::~DirHistoryQueue() {}
39 
clear()40 void DirHistoryQueue::clear()
41 {
42     _urlQueue.clear();
43     _currentItems.clear();
44     _currentPos = 0;
45 }
46 
currentUrl()47 QUrl DirHistoryQueue::currentUrl()
48 {
49     if(_urlQueue.count())
50         return _urlQueue[_currentPos];
51     else
52         return QUrl();
53 }
54 
setCurrentUrl(const QUrl & url)55 void DirHistoryQueue::setCurrentUrl(const QUrl &url)
56 {
57     if(_urlQueue.count())
58         _urlQueue[_currentPos] = url;
59 }
60 
currentItem()61 QString DirHistoryQueue::currentItem()
62 {
63     if(count())
64         return _currentItems[_currentPos];
65     else
66         return QString();
67 }
68 
saveCurrentItem()69 void DirHistoryQueue::saveCurrentItem()
70 {
71     // if the filesystem-url hasn't been refreshed yet,
72     // avoid saving current item for the wrong url
73     if(count() &&  _panel->virtualPath().matches(_urlQueue[_currentPos], QUrl::StripTrailingSlash))
74         _currentItems[_currentPos] = _panel->view->getCurrentItem();
75 }
76 
add(QUrl url,QString currentItem)77 void DirHistoryQueue::add(QUrl url, QString currentItem)
78 {
79     url.setPath(QDir::cleanPath(url.path()));
80 
81     if(_urlQueue.isEmpty()) {
82         _urlQueue.push_front(url);
83         _currentItems.push_front(currentItem);
84         return;
85     }
86 
87     if(_urlQueue[_currentPos].matches(url, QUrl::StripTrailingSlash)) {
88         _currentItems[_currentPos] = currentItem;
89         return;
90     }
91 
92     for (int i = 0; i < _currentPos; i++) {
93         _urlQueue.pop_front();
94         _currentItems.pop_front();
95     }
96 
97     _currentPos = 0;
98 
99     // do we have room for another ?
100     if (_urlQueue.count() > 12) { // FIXME: use user-defined size
101         // no room - remove the oldest entry
102         _urlQueue.pop_back();
103         _currentItems.pop_back();
104     }
105 
106     saveCurrentItem();
107     _urlQueue.push_front(url);
108     _currentItems.push_front(currentItem);
109 }
110 
gotoPos(int pos)111 bool DirHistoryQueue::gotoPos(int pos)
112 {
113     if(pos >= 0 && pos < _urlQueue.count()) {
114         saveCurrentItem();
115         _currentPos = pos;
116         return true;
117     }
118     return false;
119 }
120 
goBack()121 bool DirHistoryQueue::goBack()
122 {
123     return gotoPos(_currentPos + 1);
124 }
125 
goForward()126 bool DirHistoryQueue::goForward()
127 {
128     return gotoPos(_currentPos - 1);
129 }
130 
save(KConfigGroup cfg)131 void DirHistoryQueue::save(KConfigGroup cfg)
132 {
133     saveCurrentItem();
134 
135     QList<QUrl> urls;
136     foreach(const QUrl &url, _urlQueue) {
137         // make sure no passwords are permanently stored
138         QUrl safeUrl(url);
139         safeUrl.setPassword(QString());
140         urls << safeUrl;
141     }
142 
143     cfg.writeEntry("Entrys", KrServices::toStringList(urls));
144     cfg.writeEntry("CurrentItems", _currentItems);
145     cfg.writeEntry("CurrentIndex", _currentPos);
146 }
147 
restore(KConfigGroup cfg)148 bool DirHistoryQueue::restore(KConfigGroup cfg)
149 {
150     clear();
151     _urlQueue = KrServices::toUrlList(cfg.readEntry("Entrys", QStringList()));
152     _currentItems = cfg.readEntry("CurrentItems", QStringList());
153     if(!_urlQueue.count() || _urlQueue.count() != _currentItems.count()) {
154         clear();
155         return false;
156     }
157     _currentPos = cfg.readEntry("CurrentIndex", 0);
158     if(_currentPos >= _urlQueue.count() || _currentPos < 0)
159         _currentPos  = 0;
160 
161     return true;
162 }
163