scan: add select/invert buttons.
[abby.git] / src / util.cpp
blobd44c91a2b66e7d461c696fa43afd1b310c695637
1 /*
2 * abby Copyright (C) 2009 Toni Gundogdu.
3 * This file is part of abby.
5 * abby is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * abby is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include <QString>
20 #include <QProcess>
21 #include <QMessageBox>
22 #include <QFile>
23 #include <QTranslator>
24 #include <QDir>
25 #include <QTreeWidget>
26 //#include <QDebug>
28 #include "util.h"
30 static QString
31 check_path(const QStringList& paths, const QString& exec) {
32 QList<QString>::const_iterator iter;
33 QString path;
35 for (iter=paths.constBegin();
36 iter!=paths.constEnd();
37 ++iter)
39 QString tmp =
40 QString( "%1/%2" )
41 .arg(QDir::fromNativeSeparators(*iter))
42 .arg(exec);
44 tmp = QDir::toNativeSeparators(tmp);
46 if (QFile::exists(tmp)) {
47 path = tmp;
48 break;
51 return path;
54 static void
55 verify_version_output(
56 const QString& path,
57 QString& version,
58 QString& libVersion,
59 QString& libName,
60 bool *isCcliveFlag)
63 version.clear();
64 libVersion.clear();
65 libName.clear();
67 QProcess proc;
68 proc.setEnvironment(QStringList() << "CCLIVE_NO_CONFIG=1");
69 proc.setProcessChannelMode(QProcess::MergedChannels);
70 proc.start(path, QStringList() << "--version");
72 if (isCcliveFlag)
73 *isCcliveFlag = false;
75 if (!proc.waitForFinished()) {
76 throw NoCcliveException(path,
77 proc.exitCode(), proc.errorString());
79 else {
80 const QString output =
81 QString::fromLocal8Bit( proc.readAll() );
83 const int exitCode =
84 proc.exitCode();
86 if (exitCode == 0) {
87 const QString versionOutput = output;
88 // qDebug() << versionOutput;
90 const QStringList tmp =
91 versionOutput.split("\n", QString::SkipEmptyParts);
93 bool enoughOutputFlag = false;
95 if (tmp.size() >= 1) {
97 const QStringList lst =
98 tmp[0].split(" ", QString::SkipEmptyParts);
100 if (lst.size() >= 6) {
101 if (isCcliveFlag)
102 *isCcliveFlag = (lst[0] == "cclive");
104 version = lst[2];
105 libName = lst[4];
106 libVersion = lst[6];
108 enoughOutputFlag = true;
112 if (!enoughOutputFlag) {
113 throw NoCcliveException(path,
114 QObject::
115 tr("Not c/clive or it is an unsupported "
116 "version of it"));
119 else
120 throw NoCcliveException(path, exitCode, output);
124 void
125 Util::detectCclive(
126 QString& path,
127 QString& version,
128 QString& libVersion,
129 QString& libName,
130 bool *isCcliveFlag)
133 const QStringList env =
134 QProcess::systemEnvironment();
136 QRegExp re("^PATH=(.*)", Qt::CaseInsensitive);
137 env.indexOf(re);
139 const QString capt = re.capturedTexts()[1].simplified();
140 QStringList paths = capt.split(":");
142 if (paths.size() < 2) // w32
143 paths = capt.split(";");
145 if (paths.size() < 2)
146 return;
148 path = check_path(paths, "cclive");
149 if (path.isEmpty())
150 path = check_path(paths, "clive");
152 if (path.isEmpty()) {
153 // Detection from $PATH failed. Prompt user
154 // to specify the path in preferences manually.
155 throw NoCcliveException(
156 QObject::tr(
157 "Neither cclive or clive not was found in the path.\n"
158 "Please specify the path to either command in the\n"
159 "preferences."
163 else {
164 // Check --version output.
165 verify_version_output(
166 path,
167 version,
168 libVersion,
169 libName,
170 isCcliveFlag
175 void
176 Util::verifyCclivePath(
177 const QString& path,
178 QString& version,
179 QString& libVersion,
180 QString& libName,
181 bool *isCcliveFlag/*=NULL*/)
183 verify_version_output(
184 path,
185 version,
186 libVersion,
187 libName,
188 isCcliveFlag
192 void
193 Util::checkAllItems(
194 const QTreeWidget *w,
195 const Qt::CheckState& st,
196 const int column/*=0*/)
198 QTreeWidgetItemIterator iter(const_cast<QTreeWidget*>(w));
199 while (*iter) {
200 (*iter)->setCheckState(column, st);
201 ++iter;
205 void
206 Util::invertAllCheckableItems(
207 const QTreeWidget *w,
208 const int column/*=0*/)
210 QTreeWidgetItemIterator iter(const_cast<QTreeWidget*>(w));
211 while (*iter) {
212 (*iter)->setCheckState(column,
213 (*iter)->checkState(column) == Qt::Checked
214 ? Qt::Unchecked
215 : Qt::Checked
217 ++iter;
221 NoCcliveException::NoCcliveException(const QString& errmsg)
222 : errmsg(errmsg)
226 static const QString defmsg =
227 QObject::tr("Undefined path to c/clive command");
229 NoCcliveException::NoCcliveException(
230 const QString& path,
231 const QString& errmsg)
232 : errmsg(defmsg)
234 if (!path.isEmpty()) {
235 this->errmsg =
236 QString("error: %1:\n%2").arg(path).arg(errmsg);
240 NoCcliveException::NoCcliveException(
241 const QString& path,
242 const int& exitCode,
243 const QString& output)
244 : errmsg(defmsg)
246 if (!path.isEmpty()) {
247 this->errmsg = QString(
248 QObject::
249 tr("%1 exited with %2:\n%3")
250 .arg(path)
251 .arg(exitCode)
252 .arg(output)
257 const QString&
258 NoCcliveException::what() const {
259 return errmsg;