1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of Qt Creator.
7 **
8 ** Commercial License Usage
9 ** Licensees holding valid commercial Qt licenses may use this file in
10 ** accordance with the commercial license agreement provided with the
11 ** Software or, alternatively, in accordance with the terms contained in
12 ** a written agreement between you and The Qt Company. For licensing terms
13 ** and conditions see https://www.qt.io/terms-conditions. For further
14 ** information use the contact form at https://www.qt.io/contact-us.
15 **
16 ** GNU General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU
18 ** General Public License version 3 as published by the Free Software
19 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
20 ** included in the packaging of this file. Please review the following
21 ** information to ensure the GNU General Public License requirements will
22 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
23 **
24 ****************************************************************************/
25 
26 #include "remotemodel.h"
27 #include "gitclient.h"
28 
29 #include <utils/algorithm.h>
30 
31 namespace Git {
32 namespace Internal {
33 
34 // ------ RemoteModel
RemoteModel(QObject * parent)35 RemoteModel::RemoteModel(QObject *parent) : QAbstractTableModel(parent)
36 { }
37 
allRemoteNames() const38 QStringList RemoteModel::allRemoteNames() const
39 {
40     return Utils::transform(m_remotes, &Remote::name);
41 }
42 
remoteName(int row) const43 QString RemoteModel::remoteName(int row) const
44 {
45     return m_remotes.at(row).name;
46 }
47 
remoteUrl(int row) const48 QString RemoteModel::remoteUrl(int row) const
49 {
50     return m_remotes.at(row).url;
51 }
52 
removeRemote(int row)53 bool RemoteModel::removeRemote(int row)
54 {
55     QString output;
56     QString error;
57     bool success = GitClient::instance()->synchronousRemoteCmd(
58                 m_workingDirectory, {"rm", remoteName(row)}, &output, &error);
59     if (success)
60         success = refresh(m_workingDirectory, &error);
61     return success;
62 }
63 
addRemote(const QString & name,const QString & url)64 bool RemoteModel::addRemote(const QString &name, const QString &url)
65 {
66     QString output;
67     QString error;
68     if (name.isEmpty() || url.isEmpty())
69         return false;
70 
71     bool success = GitClient::instance()->synchronousRemoteCmd(
72                 m_workingDirectory, {"add", name, url}, &output, &error);
73     if (success)
74         success = refresh(m_workingDirectory, &error);
75     return success;
76 }
77 
renameRemote(const QString & oldName,const QString & newName)78 bool RemoteModel::renameRemote(const QString &oldName, const QString &newName)
79 {
80     QString output;
81     QString error;
82     bool success = GitClient::instance()->synchronousRemoteCmd(
83                 m_workingDirectory, {"rename", oldName, newName}, &output, &error);
84     if (success)
85         success = refresh(m_workingDirectory, &error);
86     return success;
87 }
88 
updateUrl(const QString & name,const QString & newUrl)89 bool RemoteModel::updateUrl(const QString &name, const QString &newUrl)
90 {
91     QString output;
92     QString error;
93     bool success = GitClient::instance()->synchronousRemoteCmd(
94                 m_workingDirectory, {"set-url", name, newUrl}, &output, &error);
95     if (success)
96         success = refresh(m_workingDirectory, &error);
97     return success;
98 }
99 
workingDirectory() const100 QString RemoteModel::workingDirectory() const
101 {
102     return m_workingDirectory;
103 }
104 
remoteCount() const105 int RemoteModel::remoteCount() const
106 {
107     return m_remotes.size();
108 }
109 
rowCount(const QModelIndex & parent) const110 int RemoteModel::rowCount(const QModelIndex &parent) const
111 {
112     Q_UNUSED(parent)
113     return remoteCount();
114 }
115 
columnCount(const QModelIndex & parent) const116 int RemoteModel::columnCount(const QModelIndex &parent) const
117 {
118     Q_UNUSED(parent)
119     return 2;
120 }
121 
data(const QModelIndex & index,int role) const122 QVariant RemoteModel::data(const QModelIndex &index, int role) const
123 {
124     const int row = index.row();
125     switch (role) {
126     case Qt::DisplayRole:
127     case Qt::EditRole:
128         if (index.column() == 0)
129             return remoteName(row);
130         else
131             return remoteUrl(row);
132     default:
133         break;
134     }
135     return QVariant();
136 }
137 
headerData(int section,Qt::Orientation orientation,int role) const138 QVariant RemoteModel::headerData(int section, Qt::Orientation orientation, int role) const
139 {
140     if (role != Qt::DisplayRole || orientation != Qt::Horizontal)
141         return QVariant();
142 
143     return (section == 0) ? tr("Name") : tr("URL");
144 }
145 
setData(const QModelIndex & index,const QVariant & value,int role)146 bool RemoteModel::setData(const QModelIndex &index, const QVariant &value, int role)
147 {
148     if (role != Qt::EditRole)
149         return false;
150 
151     const QString name = remoteName(index.row());
152     const QString url = remoteUrl(index.row());
153     switch (index.column()) {
154     case 0:
155         if (name == value.toString())
156             return true;
157         return renameRemote(name, value.toString());
158     case 1:
159         if (url == value.toString())
160             return true;
161         return updateUrl(name, value.toString());
162     default:
163         return false;
164     }
165 }
166 
flags(const QModelIndex & index) const167 Qt::ItemFlags RemoteModel::flags(const QModelIndex &index) const
168 {
169     Q_UNUSED(index)
170     return m_flags;
171 }
172 
clear()173 void RemoteModel::clear()
174 {
175     if (m_remotes.isEmpty())
176         return;
177     beginResetModel();
178     m_remotes.clear();
179     endResetModel();
180 }
181 
refresh(const QString & workingDirectory,QString * errorMessage)182 bool RemoteModel::refresh(const QString &workingDirectory, QString *errorMessage)
183 {
184     m_workingDirectory = workingDirectory;
185 
186     // get list of remotes.
187     QMap<QString,QString> remotesList
188             = GitClient::instance()->synchronousRemotesList(workingDirectory, errorMessage);
189 
190     beginResetModel();
191     m_remotes.clear();
192     const QList<QString> remotes = remotesList.keys();
193     for (const QString &remoteName : remotes) {
194         Remote newRemote;
195         newRemote.name = remoteName;
196         newRemote.url = remotesList.value(remoteName);
197         m_remotes.push_back(newRemote);
198     }
199     endResetModel();
200     return true;
201 }
202 
findRemoteByName(const QString & name) const203 int RemoteModel::findRemoteByName(const QString &name) const
204 {
205     const int count = remoteCount();
206     for (int i = 0; i < count; i++)
207         if (remoteName(i) == name)
208             return i;
209     return -1;
210 }
211 
212 } // namespace Internal
213 } // namespace Git
214 
215