OSDN Git Service

Update license.
[qt-creator-jp/qt-creator-jp.git] / src / plugins / vcsbase / nicknamedialog.cpp
1 /**************************************************************************
2 **
3 ** This file is part of Qt Creator
4 **
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
6 **
7 ** Contact: Nokia Corporation (info@qt.nokia.com)
8 **
9 **
10 ** GNU Lesser General Public License Usage
11 **
12 ** This file may be used under the terms of the GNU Lesser General Public
13 ** License version 2.1 as published by the Free Software Foundation and
14 ** appearing in the file LICENSE.LGPL included in the packaging of this file.
15 ** Please review the following information to ensure the GNU Lesser General
16 ** Public License version 2.1 requirements will be met:
17 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 **
19 ** In addition, as a special exception, Nokia gives you certain additional
20 ** rights. These rights are described in the Nokia Qt LGPL Exception
21 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 **
23 ** Other Usage
24 **
25 ** Alternatively, this file may be used in accordance with the terms and
26 ** conditions contained in a signed written agreement between you and Nokia.
27 **
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
30 **
31 **************************************************************************/
32
33 #include "nicknamedialog.h"
34 #include "ui_nicknamedialog.h"
35
36 #include <QtCore/QDebug>
37 #include <QtCore/QFile>
38 #include <QtCore/QDir>
39 #include <QtGui/QPushButton>
40 #include <QtGui/QStandardItemModel>
41 #include <QtGui/QSortFilterProxyModel>
42
43 enum { NickNameRole = Qt::UserRole + 1 };
44
45 namespace VCSBase {
46 namespace Internal {
47
48 // For code clarity, a struct representing the entries of a mail map file
49 // with parse and model functions.
50 struct NickNameEntry {
51     void clear();
52     bool parse(const QString &);
53     QString nickName() const;
54     QList<QStandardItem *> toModelRow() const;
55     static QString nickNameOf(const QStandardItem *item);
56
57     QString name;
58     QString email;
59     QString aliasName;
60     QString aliasEmail;
61 };
62
63 void NickNameEntry::clear()
64 {
65     name.clear();
66     email.clear();
67     aliasName.clear();
68     aliasEmail.clear();
69 }
70
71 // Parse "Hans Mustermann <HM@acme.de> [Alias [<alias@acme.de>]]"
72
73 bool NickNameEntry::parse(const QString &l)
74 {
75     clear();
76     const QChar lessThan = QLatin1Char('<');
77     const QChar greaterThan = QLatin1Char('>');
78     // Get first name/mail pair
79     int mailPos = l.indexOf(lessThan);
80     if (mailPos == -1)
81         return false;
82     name = l.mid(0, mailPos).trimmed();
83     mailPos++;
84     const int mailEndPos = l.indexOf(greaterThan, mailPos);
85     if (mailEndPos == -1)
86         return false;
87     email = l.mid(mailPos, mailEndPos - mailPos);
88     // get optional 2nd name/mail pair
89     const int aliasNameStart = mailEndPos + 1;
90     if (aliasNameStart >= l.size())
91         return true;
92     int aliasMailPos = l.indexOf(lessThan, aliasNameStart);
93     if (aliasMailPos == -1) {
94         aliasName =l.mid(aliasNameStart, l.size() -  aliasNameStart).trimmed();
95         return true;
96     }
97     aliasName = l.mid(aliasNameStart, aliasMailPos - aliasNameStart).trimmed();
98     aliasMailPos++;
99     const int aliasMailEndPos = l.indexOf(greaterThan, aliasMailPos);
100     if (aliasMailEndPos == -1)
101         return true;
102     aliasEmail = l.mid(aliasMailPos, aliasMailEndPos - aliasMailPos);
103     return true;
104 }
105
106 // Format "Hans Mustermann <HM@acme.de>"
107 static inline QString formatNick(const QString &name, const QString &email)
108 {
109     QString rc = name;
110     if (!email.isEmpty()) {
111         rc += QLatin1String(" <");
112         rc += email;
113         rc += QLatin1Char('>');
114     }
115     return rc;
116 }
117
118 QString NickNameEntry::nickName() const
119 {
120     return aliasName.isEmpty() ? formatNick(name, email) : formatNick(aliasName, aliasEmail);
121 }
122
123 QList<QStandardItem *> NickNameEntry::toModelRow() const
124 {
125     const QVariant nickNameData = nickName();
126     const Qt::ItemFlags flags = Qt::ItemIsSelectable|Qt::ItemIsEnabled;
127     QStandardItem *i1 = new QStandardItem(name);
128     i1->setFlags(flags);
129     i1->setData(nickNameData, NickNameRole);
130     QStandardItem *i2 = new QStandardItem(email);
131     i1->setFlags(flags);
132     i2->setData(nickNameData, NickNameRole);
133     QStandardItem *i3 = new QStandardItem(aliasName);
134     i3->setFlags(flags);
135     i3->setData(nickNameData, NickNameRole);
136     QStandardItem *i4 = new QStandardItem(aliasEmail);
137     i4->setFlags(flags);
138     i4->setData(nickNameData, NickNameRole);
139     QList<QStandardItem *> row;
140     row << i1 << i2 << i3 << i4;
141     return row;
142 }
143
144 QString NickNameEntry::nickNameOf(const QStandardItem *item)
145 {
146     return item->data(NickNameRole).toString();
147 }
148
149 QDebug operator<<(QDebug d, const NickNameEntry &e)
150 {
151     d.nospace() << "Name='" << e.name  << "' Mail='" << e.email
152             << " Alias='" << e.aliasName << " AliasEmail='" << e.aliasEmail << "'\n";
153     return  d;
154 }
155
156 NickNameDialog::NickNameDialog(QStandardItemModel *model, QWidget *parent) :
157         QDialog(parent),
158         m_ui(new Ui::NickNameDialog),
159         m_model(model),
160         m_filterModel(new QSortFilterProxyModel(this))
161 {
162     setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
163     m_ui->setupUi(this);
164     okButton()->setEnabled(false);
165
166     // Populate model and grow tree to accommodate it
167     m_filterModel->setSourceModel(model);
168     m_filterModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
169     m_ui->filterTreeView->setModel(m_filterModel);
170     const int columnCount = m_filterModel->columnCount();
171     int treeWidth = 0;
172     for (int c = 0; c < columnCount; c++) {
173         m_ui->filterTreeView->resizeColumnToContents(c);
174         treeWidth += m_ui->filterTreeView->columnWidth(c);
175     }
176     m_ui->filterTreeView->setMinimumWidth(treeWidth + 20);
177     connect(m_ui->filterTreeView, SIGNAL(doubleClicked(QModelIndex)), this,
178             SLOT(slotDoubleClicked(QModelIndex)));
179     connect(m_ui->filterTreeView->selectionModel(), SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),
180             this, SLOT(slotCurrentItemChanged(QModelIndex)));
181     connect(m_ui->filterLineEdit, SIGNAL(filterChanged(QString)),
182             m_filterModel, SLOT(setFilterFixedString(QString)));
183 }
184
185 NickNameDialog::~NickNameDialog()
186 {
187     delete m_ui;
188 }
189
190 QPushButton *NickNameDialog::okButton() const
191 {
192     return m_ui->buttonBox->button(QDialogButtonBox::Ok);
193 }
194
195 void NickNameDialog::slotCurrentItemChanged(const QModelIndex &index)
196 {
197     okButton()->setEnabled(index.isValid());
198 }
199
200 void NickNameDialog::slotDoubleClicked(const QModelIndex &)
201 {
202     if (okButton()->isEnabled())
203         okButton()->animateClick();
204 }
205
206 QString NickNameDialog::nickName() const
207 {
208     const QModelIndex index = m_ui->filterTreeView->selectionModel()->currentIndex();
209     if (index.isValid()) {
210         const QModelIndex sourceIndex = m_filterModel->mapToSource(index);
211         if (const QStandardItem *item = m_model->itemFromIndex(sourceIndex))
212             return NickNameEntry::nickNameOf(item);
213     }
214     return QString();
215 }
216
217 QStandardItemModel *NickNameDialog::createModel(QObject *parent)
218 {
219     QStandardItemModel *model = new QStandardItemModel(parent);
220     QStringList headers;
221     headers << tr("Name") << tr("E-mail")
222             << tr("Alias") << tr("Alias e-mail");
223     model->setHorizontalHeaderLabels(headers);
224     return model;
225 }
226
227 bool NickNameDialog::populateModelFromMailCapFile(const QString &fileName,
228                                                   QStandardItemModel *model,
229                                                   QString *errorMessage)
230 {
231     if (const int rowCount = model->rowCount())
232         model->removeRows(0, rowCount);
233     if (fileName.isEmpty())
234         return true;
235     QFile file(fileName);
236     if (!file.open(QIODevice::ReadOnly|QIODevice::Text)) {
237          *errorMessage = tr("Cannot open '%1': %2").
238                          arg(QDir::toNativeSeparators(fileName), file.errorString());
239          return false;
240     }
241     // Split into lines and read
242     NickNameEntry entry;
243     const QStringList lines = QString::fromUtf8(file.readAll()).trimmed().split(QLatin1Char('\n'));
244     const int count = lines.size();
245     for (int i = 0; i < count; i++) {
246         if (entry.parse(lines.at(i))) {
247             model->appendRow(entry.toModelRow());
248         } else {
249             qWarning("%s: Invalid mail cap entry at line %d: '%s'\n",
250                      qPrintable(QDir::toNativeSeparators(fileName)),
251                      i + 1, qPrintable(lines.at(i)));
252         }
253     }
254     model->sort(0);
255     return true;
256 }
257
258 QStringList NickNameDialog::nickNameList(const QStandardItemModel *model)
259 {
260     QStringList  rc;
261     const int rowCount = model->rowCount();
262     for (int r = 0; r < rowCount; r++)
263         rc.push_back(NickNameEntry::nickNameOf(model->item(r, 0)));
264     return rc;
265 }
266
267 }
268 }