1 /*
2  * Port for usage with qt-framework and development for kdesvn
3  * Copyright (C) 2005-2009 by Rajko Albrecht (ral@alwins-world.de)
4  * http://kdesvn.alwins-world.de
5  */
6 /*
7  * ====================================================================
8  * Copyright (c) 2002-2005 The RapidSvn Group.  All rights reserved.
9  * dev@rapidsvn.tigris.org
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation; either
14  * version 2.1 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with this library (in the file LGPL.txt); if not,
23  * write to the Free Software Foundation, Inc., 51 Franklin St,
24  * Fifth Floor, Boston, MA  02110-1301  USA
25  *
26  * This software consists of voluntary contributions made by many
27  * individuals.  For exact contribution history, see the revision
28  * history and logs, available at http://rapidsvn.tigris.org/.
29  * ====================================================================
30  */
31 
32 // svncpp
33 #include "status.h"
34 #include "svnqt/svnqt_defines.h"
35 #include "svnqt/path.h"
36 #include "svnqt/url.h"
37 
38 #include "svn_path.h"
39 
40 namespace svn
41 {
42 class SVNQT_NOEXPORT Status_private
43 {
44 public:
45     Status_private();
46     virtual ~Status_private();
47     /**
48      * Initialize structures
49      *
50      * @param path
51      * @param status if NULL isVersioned will be false
52      */
53     void init(const QString &path, const svn_client_status_t *status);
54     void init(const QString &path, const Status_private &src);
55     void init(const QString &url, const DirEntry &src);
56     void init(const QString &url, const InfoEntry &src);
57 
58     void setPath(const QString &);
59 
60     QString m_Path;
61     bool m_isVersioned;
62     bool m_hasReal;
63     LockEntry m_Lock;
64     Entry m_entry;
65 
66     svn_wc_status_kind m_node_status, m_text_status, m_prop_status, m_repos_text_status, m_repos_prop_status;
67     bool m_copied, m_switched;
68 };
69 
Status_private()70 Status_private::Status_private()
71     : m_Path()
72     , m_isVersioned(false)
73     , m_hasReal(false)
74     , m_node_status(svn_wc_status_none)
75     , m_text_status(svn_wc_status_none)
76     , m_prop_status(svn_wc_status_none)
77     , m_repos_text_status(svn_wc_status_none)
78     , m_repos_prop_status(svn_wc_status_none)
79     , m_copied(false)
80     , m_switched(false)
81 {
82 }
83 
~Status_private()84 Status_private::~ Status_private()
85 {
86 }
87 
setPath(const QString & aPath)88 void Status_private::setPath(const QString &aPath)
89 {
90     Pool pool;
91     if (!Url::isValid(aPath)) {
92         m_Path = aPath;
93     } else {
94         const char *int_path = svn_path_uri_decode(aPath.toUtf8(), pool.pool());
95         m_Path = QString::fromUtf8(int_path);
96     }
97 }
98 
init(const QString & path,const svn_client_status_t * status)99 void Status_private::init(const QString &path, const svn_client_status_t *status)
100 {
101     setPath(path);
102     if (!status) {
103         m_isVersioned = false;
104         m_hasReal = false;
105         m_entry = Entry();
106         m_Lock = LockEntry();
107     } else {
108         // now duplicate the contents
109         // svn 1.7 does not count ignored entries as versioned but we do here...
110         m_isVersioned = status->node_status > svn_wc_status_unversioned;
111         m_hasReal = m_isVersioned &&
112                     status->node_status != svn_wc_status_ignored;
113         m_entry = Entry(status);
114         m_node_status = status->node_status;
115         m_text_status = status->text_status;
116         m_prop_status = status->prop_status;
117         m_copied = status->copied != 0;
118         m_switched = status->switched != 0;
119         m_repos_text_status = status->repos_text_status;
120         m_repos_prop_status = status->repos_prop_status;
121         if (status->repos_lock) {
122             m_Lock.init(status->repos_lock->creation_date,
123                         status->repos_lock->expiration_date,
124                         status->repos_lock->owner,
125                         status->repos_lock->comment,
126                         status->repos_lock->token);
127         } else {
128             m_Lock = LockEntry();
129         }
130     }
131 }
132 
133 void
init(const QString & path,const Status_private & src)134 Status_private::init(const QString &path, const Status_private &src)
135 {
136     setPath(path);
137     m_Lock = src.m_Lock;
138     m_entry = src.m_entry;
139     m_isVersioned = src.m_isVersioned;
140     m_hasReal = src.m_hasReal;
141     m_node_status = src.m_node_status;
142     m_text_status = src.m_text_status;
143     m_prop_status = src.m_prop_status;
144     m_repos_text_status = src.m_repos_text_status;
145     m_repos_prop_status = src.m_repos_prop_status;
146     m_copied = src.m_copied;
147     m_switched = src.m_switched;
148 }
149 
init(const QString & url,const DirEntry & src)150 void Status_private::init(const QString &url, const DirEntry &src)
151 {
152     m_entry = Entry(url, src);
153     setPath(url);
154     m_node_status = svn_wc_status_normal;
155     m_text_status = svn_wc_status_normal;
156     m_prop_status = svn_wc_status_normal;
157     if (!src.isEmpty()) {
158         m_Lock = src.lockEntry();
159         m_isVersioned = true;
160         m_hasReal = true;
161     }
162     m_switched = false;
163     m_repos_text_status = svn_wc_status_normal;
164     m_repos_prop_status = svn_wc_status_normal;
165 }
166 
init(const QString & url,const InfoEntry & src)167 void Status_private::init(const QString &url, const InfoEntry &src)
168 {
169     m_entry = Entry(url, src);
170     setPath(url);
171     m_Lock = src.lockEntry();
172     m_node_status = svn_wc_status_normal;
173     m_text_status = svn_wc_status_normal;
174     m_prop_status = svn_wc_status_normal;
175     m_repos_text_status = svn_wc_status_normal;
176     m_repos_prop_status = svn_wc_status_normal;
177     m_isVersioned = true;
178     m_hasReal = true;
179 }
180 
Status(const Status & src)181 Status::Status(const Status &src)
182     : m_Data(new Status_private())
183 {
184     if (&src != this) {
185         if (src.m_Data) {
186             m_Data->init(src.m_Data->m_Path, *(src.m_Data));
187         } else {
188             m_Data->init(QString(), nullptr);
189         }
190     }
191 }
192 
Status(const char * path,const svn_client_status_t * status)193 Status::Status(const char *path, const svn_client_status_t *status)
194   : m_Data(new Status_private())
195 {
196     m_Data->init(QString::fromUtf8(path), status);
197 }
198 
Status(const QString & path)199 Status::Status(const QString &path)
200     : m_Data(new Status_private())
201 {
202     m_Data->init(path, nullptr);
203 }
204 
Status(const QString & url,const DirEntry & src)205 Status::Status(const QString &url, const DirEntry &src)
206     : m_Data(new Status_private())
207 {
208     m_Data->init(url, src);
209 }
210 
Status(const QString & url,const InfoEntry & src)211 Status::Status(const QString &url, const InfoEntry &src)
212     : m_Data(new Status_private())
213 {
214     m_Data->init(url, src);
215 }
216 
~Status()217 Status::~Status()
218 {
219     delete m_Data;
220 }
221 
222 Status &
operator =(const Status & status)223 Status::operator=(const Status &status)
224 {
225     if (this == &status) {
226         return *this;
227     }
228     if (status.m_Data) {
229         m_Data->init(status.m_Data->m_Path, *(status.m_Data));
230     } else {
231         m_Data->init(status.m_Data->m_Path, nullptr);
232     }
233     return *this;
234 }
235 
236 const LockEntry &
lockEntry() const237 Status::lockEntry() const
238 {
239     return m_Data->m_Lock;
240 }
241 svn_wc_status_kind
reposPropStatus() const242 Status::reposPropStatus() const
243 {
244     return m_Data->m_repos_prop_status;
245 }
246 svn_wc_status_kind
reposTextStatus() const247 Status::reposTextStatus() const
248 {
249     return m_Data->m_repos_text_status;
250 }
251 bool
isSwitched() const252 Status::isSwitched() const
253 {
254     return m_Data->m_switched != 0;
255 }
256 bool
isCopied() const257 Status::isCopied() const
258 {
259     return m_Data->m_copied;
260 }
261 
262 bool
isLocked() const263 Status::isLocked() const
264 {
265     return m_Data->m_Lock.Locked();
266 }
267 
268 bool
isModified() const269 Status::isModified()const
270 {
271     return textStatus() == svn_wc_status_modified || propStatus() == svn_wc_status_modified
272            || textStatus() == svn_wc_status_replaced;
273 }
274 
275 bool
isRealVersioned() const276 Status::isRealVersioned()const
277 {
278     return m_Data->m_hasReal;
279 }
280 
281 bool
isVersioned() const282 Status::isVersioned() const
283 {
284     return m_Data->m_isVersioned;
285 }
286 
287 svn_wc_status_kind
nodeStatus() const288 Status::nodeStatus() const
289 {
290     return m_Data->m_node_status;
291 }
292 
293 svn_wc_status_kind
propStatus() const294 Status::propStatus() const
295 {
296     return m_Data->m_prop_status;
297 }
298 
299 svn_wc_status_kind
textStatus() const300 Status::textStatus() const
301 {
302     return m_Data->m_text_status;
303 }
304 
305 const Entry &
entry() const306 Status::entry() const
307 {
308     return m_Data->m_entry;
309 }
310 
311 const QString &
path() const312 Status::path() const
313 {
314     return m_Data->m_Path;
315 }
316 
317 bool
validReposStatus() const318 Status::validReposStatus()const
319 {
320     return reposTextStatus() != svn_wc_status_none || reposPropStatus() != svn_wc_status_none;
321 }
322 
323 bool
validLocalStatus() const324 Status::validLocalStatus()const
325 {
326     return textStatus() != svn_wc_status_none || propStatus() != svn_wc_status_none;
327 }
328 }
329