source: src-qt4/pc-controlpanel/item.cpp @ 18c4ab8

9.2-releasereleng/10.0releng/10.0.1releng/10.0.2
Last change on this file since 18c4ab8 was 18c4ab8, checked in by Ken Moore <ken@…>, 8 months ago

Fix compilation warnings for pc-controlpanel on 10.x

  • Property mode set to 100644
File size: 12.3 KB
Line 
1/**************************************************************************
2*   Copyright (C) 2011 by Yuri Momotyuk                                   *
3*   yurkis@gmail.com                                                      *
4*                                                                         *
5*   Permission is hereby granted, free of charge, to any person obtaining *
6*   a copy of this software and associated documentation files (the       *
7*   "Software"), to deal in the Software without restriction, including   *
8*   without limitation the rights to use, copy, modify, merge, publish,   *
9*   distribute, sublicense, and/or sell copies of the Software, and to    *
10*   permit persons to whom the Software is furnished to do so, subject to *
11*   the following conditions:                                             *
12*                                                                         *
13*   The above copyright notice and this permission notice shall be        *
14*   included in all copies or substantial portions of the Software.       *
15*                                                                         *
16*   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       *
17*   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    *
18*   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*
19*   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR     *
20*   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
21*   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR *
22*   OTHER DEALINGS IN THE SOFTWARE.                                       *
23***************************************************************************/
24
25#include "item.h"
26
27#include <QSettings>
28#include <QLocale>
29#include <QFile>
30#include <QTextStream>
31#include <QProcess>
32#include <QMessageBox>
33#include <QDebug>
34#include <QDir>
35#include <QTemporaryFile>
36#include <unistd.h>
37#include <stdlib.h>
38#include <sys/stat.h>
39
40#include "../config.h"
41
42#include <iostream>
43
44const char* const PBI_NAME_FIELD = "PC-PBIName";
45const char* const TRY_MESSAGE_FIELD = "PC-TryMessage";
46const char* const TRY_COMMAND_FIELD = "PC-TryCommand";
47const char* const REQUIRED_DE = "PC-RequiredDE";
48
49const char* const PBI_PREFIX_MACRO = "%PBI_PREFIX%";
50
51const QString DEFAULT_ICON_LOCATION = PREFIX + "/share/pcbsd/pc-controlpanel/icons/";
52const char* const DEFAULT_ICON = "preferences-other.png";
53
54const QString SU_NAMES[] = {QString("pc-su "), QString("kdesu "), QString("gtksu ")};
55const QString SUDO_COMMAND("sudo ");
56
57QCPItem::QCPItem():misValid(false), misMsgBox(false), isRequireRoot(false),isSudo(false)
58{
59}
60
61///////////////////////////////////////////////////////////////////////////////
62bool QCPItem::readDE(QString FileName, const QVector<QString>& vEnabledDE)
63{
64    QString Str;
65
66    bool isPBISoftware = false;
67    misValid= false;
68    misSubstFound = false;
69    misUseXDG = false;
70    if (InstalledDEList.active())
71        misUseXDG = InstalledDEList.active()->misXDG;
72
73    misXDGLaunch = false;
74
75    SPBIInfo PBIInfo;
76    mvEnabledDE = vEnabledDE;
77
78    //Try to open file
79    QSettings Reader(FileName, QSettings::IniFormat);
80    if (Reader.status() != QSettings::NoError)
81        return false;
82    Reader.setIniCodec("UTF-8");
83
84    Reader.beginGroup("Desktop Entry");
85
86    /**
87          If type of desktop shortcut is 'application' or 'service' we will try
88          to launch application using own launch() realization.
89          For another type (url for example) we use xdg for launch if XDGLaunch
90          is true.
91        */
92
93    // If type is not application and we do not use xdg-launch - return false
94    QString Type=Reader.value("Type").toString();
95    if (Type.compare(QString("application"), Qt::CaseInsensitive))
96    {
97        //if type of shortcut is not application and we can use xdg...
98        if (misUseXDG)
99            misXDGLaunch = true;
100        else
101            return false;
102    }
103
104    Str= Reader.value(PBI_NAME_FIELD).toString();
105    if (Str.length())
106    {       
107        if (!InstalledPBIs.findByName(Str, PBIInfo, Qt::CaseInsensitive))
108            return false;
109        /*if (!getPBIPath(Str, mPBIPath))
110                        return false;*/
111        mPBIPath = PBIInfo.mPrefix;
112        isPBISoftware = true;
113    }
114
115    //Check TryExec field
116    Str=  Reader.value("TryExec").toString();
117    if (Str.length())
118    {
119        if (Str.contains(PBI_PREFIX_MACRO))
120            misSubstFound = true;
121        Str.replace(PBI_PREFIX_MACRO, PBIInfo.mPrefix);
122        struct stat sts;
123        if ((0 != stat(qPrintable(Str),&sts))
124            &&(0 != access(qPrintable(Str), X_OK)))
125            return false;
126    }
127
128    // Check PC-RequiredDE field (vmEnabledDE is a vector of names enabled DEs)
129    Str = Reader.value(REQUIRED_DE).toString();
130    if (Str.length())
131    {
132        bool found = false;
133        for(int i = 0; i< mvEnabledDE.size(); i++)
134        {
135            Str=Str.trimmed();
136            if (!Str.compare(mvEnabledDE[i].trimmed(), Qt::CaseInsensitive))
137            {
138                found = true;
139                mRequiredDE= Str;
140                break;
141            }//if found
142        }//for all enabled DE
143        if (!found)
144            return false;
145    }
146
147    //Check TryCommand extention field
148    Str= Reader.value(TRY_COMMAND_FIELD).toString();
149    if (Str.length())
150    {
151        QTemporaryFile tmpFile;
152        if (!tmpFile.open())
153        {
154            return false;
155        }
156        QTextStream out(&tmpFile);
157        out<<Str<<"\n";
158        out.flush();
159        tmpFile.flush();
160
161        QProcess shell_proc;
162        shell_proc.start("/bin/sh",QStringList()<<tmpFile.fileName());
163        shell_proc.waitForFinished(7000);
164        if (shell_proc.exitCode())
165            return false;
166    }
167    /*if (Str.length())
168    {
169        if (system(Str.toLatin1()) != 0)
170            return false;
171    }*/
172
173
174    mOriginalName = Reader.value("Name").toString();
175    if (!mOriginalName.length())
176    {
177        mOriginalName = Reader.value("GenericName").toString();
178        if (!mOriginalName.length())
179            return false;
180    }
181
182    //Get Name or GenericName field
183    if (!getLocalizedField(Reader, "Name",  Str))
184    {       
185        if (!getLocalizedField(Reader, "GenericName",  Str))
186            return false;
187    }
188    setText(Str);
189    mName=Str;
190
191    //Get and check Exec field
192    mExecCommand= Reader.value("Exec").toString();
193    if (!mExecCommand.length() && !misXDGLaunch)
194        return false;
195    if (Str.contains(PBI_PREFIX_MACRO))
196        misSubstFound = true;
197    mExecCommand.replace(PBI_PREFIX_MACRO, PBIInfo.mPrefix);
198
199    //Get Path field
200    mPath= Reader.value("Path").toString();
201    if (mPath.contains(PBI_PREFIX_MACRO))
202           misSubstFound = true;
203    mPath.replace(PBI_PREFIX_MACRO, PBIInfo.mPrefix);
204
205    //Get Comment field
206    if (getLocalizedField(Reader, "Comment",  Str))
207    {
208        setToolTip(Str);
209    }
210
211    //Get Icon field, try to load icon
212    mIconFile=  Reader.value("Icon").toString();
213    QIcon anIcon;
214    //If .desktop file is not contain Icon field try to get icon from pbi info
215    if (!mIconFile.length() && isPBISoftware)
216        mIconFile = PBIInfo.mIcon;
217
218    if (mIconFile.length())
219    {
220        if (Str.contains(PBI_PREFIX_MACRO))
221            misSubstFound = true;
222
223        mIconFile.replace(PBI_PREFIX_MACRO, PBIInfo.mPrefix);
224        //mIconFile.replace("//","/");
225        anIcon = QIcon(mIconFile);
226        if (!anIcon.availableSizes().size())
227        {
228            //if icon loading failed (from absolute path) try to load icon
229            // from theme
230            anIcon = QIcon::fromTheme(mIconFile);
231        }
232        if (!anIcon.availableSizes().size())
233        {
234            QString FileName = QString(DEFAULT_ICON_LOCATION) + mIconFile;
235
236            anIcon = QIcon(FileName);
237        }
238        if (!anIcon.availableSizes().size())
239        {
240            anIcon = QIcon(QString(DEFAULT_ICON_LOCATION) + DEFAULT_ICON);
241        }
242    }//if got Icon field
243    else
244    {
245        anIcon = QIcon(QString(DEFAULT_ICON_LOCATION) + DEFAULT_ICON);
246    }
247    if (anIcon.availableSizes().size())
248        setIcon(anIcon);
249
250
251    //Get TryMessage extended field
252    if (getLocalizedField(Reader, TRY_MESSAGE_FIELD, mMsgBoxText))
253    {
254        misMsgBox= true;
255    }
256    else
257    {
258        misMsgBox= false;
259    }
260
261    //Get Tags
262    mTags.clear();
263
264    QString Tags= Reader.value("PC-Tags").toString();
265    mTags=Tags.split(",",QString::SkipEmptyParts);
266    if (getLocalizedField(Reader, "PC-Tags", Tags))
267    {
268        mTags<<Tags.split(",",QString::SkipEmptyParts);
269    }
270    mTags.removeDuplicates();
271
272    // Check if item require root access
273    isRequireRoot = false;
274    QString tmp = mExecCommand.trimmed();
275
276    for (unsigned int i=0; i<sizeof(SU_NAMES)/sizeof(QString); i++ )
277    {
278        if (tmp.left(SU_NAMES[i].size()) == SU_NAMES[i])
279        {
280            isRequireRoot = true;
281            break;
282        }
283    }
284
285    isSudo = false;
286    if (tmp.left(SUDO_COMMAND.size()) == SUDO_COMMAND)
287        isSudo = true;
288
289    misValid= true;
290    mFileName= FileName;
291
292    return true;
293}
294
295///////////////////////////////////////////////////////////////////////////////
296bool QCPItem::getLocalizedField(const QSettings& Reader,
297                                const QString& FieldName,
298                                QString& RetVal)
299{
300    QString Str;
301    QString LocaleCountry = QLocale::system().name();
302    QString Locale= QString("[")+LocaleCountry.left(2)+QString("]");
303    LocaleCountry= QString("[")+LocaleCountry+QString("]");
304
305    RetVal= Reader.value(FieldName).toString();
306
307    Str = Reader.value(FieldName + Locale).toString();
308    if (Str.length())
309        RetVal= Str;
310
311    Str= Reader.value(FieldName+LocaleCountry).toString();
312    if (Str.length())
313        RetVal= Str;
314
315    return (bool)RetVal.length();
316}
317
318///////////////////////////////////////////////////////////////////////////////
319bool QCPItem::isValid()
320{
321    return misValid;
322}
323
324///////////////////////////////////////////////////////////////////////////////
325bool QCPItem::launch()
326{
327    if (!isValid())
328        return false;
329
330    //If shortcut contain 'TryMessage' field
331    if (misMsgBox)
332    {
333        QMessageBox msgBox;
334        msgBox.setText(mMsgBoxText);
335        msgBox.setIcon(QMessageBox::Question);
336        msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
337        msgBox.setDefaultButton(QMessageBox::Yes);
338        if (QMessageBox::Yes != msgBox.exec())
339            return true;
340    }
341
342    if (misXDGLaunch)
343        return launchXDG();
344    else
345        return launchOwn();
346}
347
348///////////////////////////////////////////////////////////////////////////////
349bool QCPItem::launchOwn()
350{
351    pid_t RetVal = fork();
352    if (!RetVal)
353    {
354        if (mPath.length())
355        {
356            chdir(qPrintable(mPath));
357        }
358        QString Str = mExecCommand;
359        Str.replace("%i", QString(" --icon ") + mIconFile);
360        Str.replace("%c", QString("\"") + text().toLocal8Bit() + QString("\""));
361        Str.replace("%k", mFileName);
362        Str.replace("%f","");
363        Str.replace("%F","");
364        Str.replace("%u","");
365        Str.replace("%U","");
366        exit (system(Str.toLatin1()));
367    }
368    return RetVal > 0;
369}
370
371///////////////////////////////////////////////////////////////////////////////
372bool QCPItem::launchXDG()
373{
374    QProcess proc;
375    QString FileToOpen = mFileName;
376
377    if (misSubstFound)
378    {
379        /* File is contain %PBI_PREFIX% macro, we must replace macro and save to
380                   temporary file */
381        QTemporaryFile outfile(QDir::tempPath()+"/XXXXXXX.desktop");
382        if (!outfile.open())
383            return false;
384        outfile.setAutoRemove(false);
385
386        QFile infile (mFileName);
387        if (!infile.open(QIODevice::ReadOnly | QIODevice::Text))
388            return false;
389
390        QTextStream out(&outfile);
391        QString Str;
392        while (!infile.atEnd())
393        {
394            Str = infile.readLine();
395            Str.replace(PBI_PREFIX_MACRO, mPBIPath);
396            out<<Str;
397        }
398        FileToOpen = outfile.fileName();
399        out.flush();
400        outfile.flush();
401    }
402    //TODO: Remove temp file!
403    proc.startDetached("xdg-open",QStringList()<<FileToOpen);
404    return true;
405}
406
407///////////////////////////////////////////////////////////////////////////////
408void QCPItem::setDisplayDEName(bool isDisplay)
409{
410    QString NewText = mName;
411    if (isDisplay && mRequiredDE.length())
412        NewText = QString("%1 - %2"). arg(mRequiredDE).arg(mName);
413    setText(NewText);
414}
Note: See TracBrowser for help on using the repository browser.