Logo Search packages:      
Sourcecode: pcp-gui version File versions

main.cpp

/*
 * Copyright (c) 2006, Ken McDonell.  All Rights Reserved.
 * Copyright (c) 2007, Aconex.  All Rights Reserved.
 * 
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 * 
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 */
#include <QtCore/QSettings>
#include <QtGui/QApplication>
#include <QtGui/QStatusBar>
#include "main.h"
#include "openviewdialog.h"

#define DESPERATE 0

int Cflag;
int Lflag;
int Wflag;
char *outfile;
char *outgeometry;
QFont globalFont;
Settings globalSettings;

// Globals used to provide single instances of classes used across pmchart
GroupControl *liveGroup;      // one metrics class group for all hosts
GroupControl *archiveGroup;   // one metrics class group for all archives
GroupControl *activeGroup;    // currently active metric fetchgroup
TimeControl *pmtime;          // one timecontrol class for pmtime
PmChart *pmchart;

static void usage(void)
{
    pmprintf("Usage: %s [options] [sources]\n\n"
"Options:\n"
"  -A align      align sample times on natural boundaries\n"
"  -a archive    add PCP log archive to metrics source list\n"
"  -c configfile initial view to load\n"
"  -C            with -c, parse config, report any errors and exit\n"
"  -CC           like -C, but also connect to pmcd to check semantics\n"
"  -g geometry   image geometry Width x Height (WxH)\n"
"  -h host       add host to list of live metrics sources\n"
#ifdef PM_USE_CONTEXT_LOCAL
"  -L            directly fetch metrics from localhost, PMCD is not used\n"
#endif
"  -n pmnsfile   use an alternative PMNS\n"
"  -o outfile    export image to outfile\n"
"  -O offset     initial offset into the time window\n"
"  -p port       port name for connection to existing time control\n"
"  -s samples    sample history [default: %d points]\n"
"  -S starttime  start of the time window\n"
"  -T endtime    end of the time window\n"
"  -t interval   sample interval [default: %d seconds]\n"
"  -v visible    visible history [default: %d points]\n"
"  -V            display pmchart version number and exit\n"
"  -W            export images using an opaque (white) background\n"
"  -Z timezone   set reporting timezone\n"
"  -z            set reporting timezone to local time of metrics source\n",
      pmProgname, PmChart::defaultSampleHistory(),
      (int)PmChart::defaultChartDelta(), PmChart::defaultVisibleHistory());
    pmflush();
    exit(1);
}

// a := a + b for struct timevals
void tadd(struct timeval *a, struct timeval *b)
{
    a->tv_usec += b->tv_usec;
    if (a->tv_usec > 1000000) {
      a->tv_usec -= 1000000;
      a->tv_sec++;
    }
    a->tv_sec += b->tv_sec;
}

//
// a : b for struct timevals ... <0 for a<b, ==0 for a==b, >0 for a>b
//
int tcmp(struct timeval *a, struct timeval *b)
{
    int res = (int)(a->tv_sec - b->tv_sec);
    if (res == 0)
      res = (int)(a->tv_usec - b->tv_usec);
    return res;
}

// convert timeval to seconds
double tosec(struct timeval t)
{
    return t.tv_sec + (t.tv_usec / 1000000.0);
}

// create a time range in seconds from (delta x points)
double torange(struct timeval t, int points)
{
    return tosec(t) * points;
}

// conversion from seconds (double precision) to struct timeval
void fromsec(double value, struct timeval *tv)
{
    tv->tv_sec = (time_t)value;
    tv->tv_usec = (long)(((value - (double)tv->tv_sec) * 1000000.0));
}

// debugging, display seconds-since-epoch in human readable format
char *timeString(double seconds)
{
    static char string[32];
    time_t secs = (time_t)seconds;
    char *s;

    s = pmCtime(&secs, string);
    s[strlen(s)-1] = '\0';
    return s;
}

// return a string containing hour and milliseconds
char *timeHiResString(double time)
{
    static char s[16];
    char m[8];
    time_t secs = (time_t)time;
    struct tm t;

    sprintf(m, "%.3f", time - floor(time));
    pmLocaltime(&secs, &t);
    sprintf(s, "%02d:%02d:%02d.%s", t.tm_hour, t.tm_min, t.tm_sec, m+2);
    s[strlen(s)-1] = '\0';
    return s;
}

double PmTime::secondsToUnits(double value, PmTime::DeltaUnits units)
{
    switch (units) {
    case Milliseconds:
      value = value * 1000.0;
      break;
    case Minutes:
      value = value / 60.0;
      break;
    case Hours:
      value = value / (60.0 * 60.0);
      break;
    case Days:
      value = value / (60.0 * 60.0 * 24.0);
      break;
    case Weeks:
      value = value / (60.0 * 60.0 * 24.0 * 7.0);
      break;
    case Seconds:
    default:
      break;
    }
    return value;
}

double PmTime::deltaValue(QString delta, PmTime::DeltaUnits units)
{
    return PmTime::secondsToUnits(delta.trimmed().toDouble(), units);
}

QString PmTime::deltaString(double value, PmTime::DeltaUnits units)
{
    QString delta;

    value = PmTime::secondsToUnits(value, units);
    if ((double)(int)value == value)
      delta.sprintf("%.2f", value);
    else
      delta.sprintf("%.6f", value);
    return delta;
}

void nomem(void)
{
    // no point trying to report anything ... dump core is the best bet
    abort();
}

void setupEnvironment(void)
{
    QString confirm = pmGetConfig("PCP_BIN_DIR");
    confirm.prepend("PCP_XCONFIRM_PROG=");
    confirm.append("/pmquery");
    putenv(strdup((const char *)confirm.toAscii()));
    if (getenv("PCP_STDERR") == NULL)     // do not overwrite, for QA
      putenv(strdup("PCP_STDERR=DISPLAY"));

    QCoreApplication::setOrganizationName("PCP");
    QCoreApplication::setApplicationName(pmProgname);
}

void writeSettings(void)
{
    QSettings userSettings;

    userSettings.beginGroup(pmProgname);
    if (globalSettings.chartDeltaModified) {
      globalSettings.chartDeltaModified = false;
      userSettings.setValue("chartDelta", globalSettings.chartDelta);
    }
    if (globalSettings.loggerDeltaModified) {
      globalSettings.loggerDeltaModified = false;
      userSettings.setValue("loggerDelta", globalSettings.loggerDelta);
    }
    if (globalSettings.sampleHistoryModified) {
      globalSettings.sampleHistoryModified = false;
      userSettings.setValue("sampleHistory", globalSettings.sampleHistory);
    }
    if (globalSettings.visibleHistoryModified) {
      globalSettings.visibleHistoryModified = false;
      userSettings.setValue("visibleHistory", globalSettings.visibleHistory);
    }
    if (globalSettings.defaultSchemeModified) {
      globalSettings.defaultSchemeModified = false;
      userSettings.setValue("defaultColorScheme",
                        globalSettings.defaultScheme.colorNames());
    }
    if (globalSettings.colorSchemesModified) {
      globalSettings.colorSchemesModified = false;
      userSettings.beginWriteArray("schemes");
      for (int i = 0; i < globalSettings.colorSchemes.size(); i++) {
          userSettings.setArrayIndex(i);
          userSettings.setValue("name",
                        globalSettings.colorSchemes[i].name());
          userSettings.setValue("colors",
                        globalSettings.colorSchemes[i].colorNames());
      }
      userSettings.endArray();
    }
    if (globalSettings.chartBackgroundModified) {
      globalSettings.chartBackgroundModified = false;
      userSettings.setValue("chartBackgroundColor",
                        globalSettings.chartBackgroundName);
    }
    if (globalSettings.chartHighlightModified) {
      globalSettings.chartHighlightModified = false;
      userSettings.setValue("chartHighlightColor",
                        globalSettings.chartHighlightName);
    }
    if (globalSettings.initialToolbarModified) {
      globalSettings.initialToolbarModified = false;
      userSettings.setValue("initialToolbar", globalSettings.initialToolbar);
    }
    if (globalSettings.nativeToolbarModified) {
      globalSettings.nativeToolbarModified = false;
      userSettings.setValue("nativeToolbar", globalSettings.nativeToolbar);
    }
    if (globalSettings.toolbarLocationModified) {
      globalSettings.toolbarLocationModified = false;
      userSettings.setValue("toolbarLocation",
                        globalSettings.toolbarLocation);
    }
    if (globalSettings.toolbarActionsModified) {
      globalSettings.toolbarActionsModified = false;
      userSettings.setValue("toolbarActions", globalSettings.toolbarActions);
    }
    userSettings.endGroup();
}

void checkHistory(int samples, int visible)
{
    // sanity checking on sample sizes
    if (samples < PmChart::minimumPoints()) {
      globalSettings.sampleHistory = PmChart::minimumPoints();
      globalSettings.sampleHistoryModified = true;
    }
    if (samples > PmChart::maximumPoints()) {
      globalSettings.sampleHistory = PmChart::maximumPoints();
      globalSettings.sampleHistoryModified = true;
    }
    if (visible < PmChart::minimumPoints()) {
      globalSettings.visibleHistory = PmChart::minimumPoints();
      globalSettings.visibleHistoryModified = true;
    }
    if (visible > PmChart::maximumPoints()) {
      globalSettings.visibleHistory = PmChart::maximumPoints();
      globalSettings.visibleHistoryModified = true;
    }
    if (samples < visible) {
      globalSettings.sampleHistory = globalSettings.visibleHistory;
      globalSettings.sampleHistoryModified = true;
    }
}

void readSettings(void)
{
    QSettings userSettings;
    userSettings.beginGroup(pmProgname);

    //
    // Parameters related to sampling
    //
    globalSettings.chartDeltaModified = false;
    globalSettings.chartDelta = userSettings.value("chartDelta",
                        PmChart::defaultChartDelta()).toDouble();
    globalSettings.loggerDeltaModified = false;
    globalSettings.loggerDelta = userSettings.value("loggerDelta",
                        PmChart::defaultLoggerDelta()).toDouble();
    globalSettings.sampleHistoryModified = false;
    globalSettings.sampleHistory = userSettings.value("sampleHistory",
                        PmChart::defaultSampleHistory()).toInt();
    globalSettings.visibleHistoryModified = false;
    globalSettings.visibleHistory = userSettings.value("visibleHistory",
                        PmChart::defaultVisibleHistory()).toInt();
    checkHistory(globalSettings.sampleHistory, globalSettings.visibleHistory);
    if (globalSettings.sampleHistoryModified) {
      userSettings.setValue("samplePoints", globalSettings.sampleHistory);
      globalSettings.sampleHistoryModified = false;
    }
    if (globalSettings.visibleHistoryModified) {
      userSettings.setValue("visiblePoints", globalSettings.visibleHistory);
      globalSettings.visibleHistoryModified = false;
    }

    //
    // Everything colour (scheme) related
    //
    QStringList colorList;
    globalSettings.defaultSchemeModified = false;
    if (userSettings.contains("defaultColorScheme") == true)
      colorList = userSettings.value("defaultColorScheme").toStringList();
    else
      colorList << "yellow" << "blue" << "red" << "green" << "violet";
    globalSettings.defaultScheme.setName("#-cycle");
    globalSettings.defaultScheme.setModified(false);
    globalSettings.defaultScheme.setColorNames(colorList);

    int size = userSettings.beginReadArray("schemes");
    for (int i = 0; i < size; i++) {
      userSettings.setArrayIndex(i);
      ColorScheme scheme;
      scheme.setName(userSettings.value("name").toString());
      scheme.setModified(false);
      scheme.setColorNames(userSettings.value("colors").toStringList());
      globalSettings.colorSchemes.append(scheme);
    }
    userSettings.endArray();

    //
    // Everything (else) colour related
    //
    globalSettings.chartBackgroundModified = false;
    globalSettings.chartBackgroundName = userSettings.value(
            "chartBackgroundColor", "#6ca2c9").toString();
    globalSettings.chartBackground = QColor(globalSettings.chartBackgroundName);

    globalSettings.chartHighlightModified = false;
    globalSettings.chartHighlightName = userSettings.value(
            "chartHighlightColor", "blue").toString();
    globalSettings.chartHighlight = QColor(globalSettings.chartHighlightName);

    //
    // Toolbar user preferences
    //
    globalSettings.initialToolbarModified = false;
    globalSettings.initialToolbar = userSettings.value(
                              "initialToolbar", 1).toInt();
    globalSettings.nativeToolbarModified = false;
    globalSettings.nativeToolbar = userSettings.value(
                              "nativeToolbar", 1).toInt();
    globalSettings.toolbarLocationModified = false;
    globalSettings.toolbarLocation = userSettings.value(
                              "toolbarLocation", 0).toInt();
    QStringList actionList;
    globalSettings.toolbarActionsModified = false;
    if (userSettings.contains("toolbarActions") == true)
      globalSettings.toolbarActions =
                  userSettings.value("toolbarActions").toStringList();
    // else: (defaults come from the pmchart.ui interface specification)

    userSettings.endGroup();
}

void readSchemes(void)
{
    QString schemes = pmGetConfig("PCP_VAR_DIR");
    QFileInfo fi(schemes.append("/config/pmchart/Schemes"));
    if (fi.exists())
      OpenViewDialog::openView(schemes.toAscii());
}

// Get next color from given scheme or from default colors for #-cycle
QColor nextColor(QString scheme, int *sequence)
{
    QList<QColor> colorList;
    int seq = (*sequence)++;

    for (int i = 0; i < globalSettings.colorSchemes.size(); i++) {
      if (globalSettings.colorSchemes[i].name() == scheme) {
          colorList = globalSettings.colorSchemes[i].colors();
          break;
      }
    }
    if (colorList.size() < 2) // common case
      colorList = globalSettings.defaultScheme.colors();
    if (colorList.size() < 2) // idiot user!?
      colorList << QColor("yellow") << QColor("blue") << QColor("red")
              << QColor("green") << QColor("violet");
    seq %= colorList.size();
    return colorList.at(seq);
}

void setupViewGlobals()
{
    int w, h, points, x, y;

    OpenViewDialog::globals(&w, &h, &points, &x, &y);
    if (w || h) {
      QSize size = pmchart->size();
      pmchart->resize(size.expandedTo(QSize(w, h)));
    }
    if (x || y) {
      QPoint pos = pmchart->pos();
      if (x) pos.setX(x);
      if (y) pos.setY(y);
      pmchart->move(pos);
    }
    if (points) {
      if (activeGroup->sampleHistory() < points)
          activeGroup->setSampleHistory(points);
      activeGroup->setVisibleHistory(points);
    }
}

int
main(int argc, char ** argv)
{
    int                 c, sts;
    int                 errflg = 0;
    char          *endnum, *msg;
    char          *pmnsfile = NULL; /* local namespace file */
    char          *Sflag = NULL;          /* argument of -S flag */
    char          *Tflag = NULL;          /* argument of -T flag */
    char          *Aflag = NULL;          /* argument of -A flag */
    char          *Oflag = NULL;          /* argument of -O flag */
    int                 zflag = 0;        /* for -z (source zone) */
    char          *tz = NULL;       /* for -Z timezone */
    int                 sh = -1;          /* sample history length */
    int                 vh = -1;          /* visible history length */
    int                 port = -1;        /* pmtime port number */
    struct timeval      delta;
    struct timeval      origin;
    struct timeval      logStartTime;
    struct timeval      logEndTime;
    struct timeval      realStartTime;
    struct timeval      realEndTime;
    struct timeval      position;
    Tab                 *tab;
    QStringList         hosts;
    QStringList         archives;
    QStringList         configs;
    QString       tzLabel;
    QString       tzString;
    static const char   *options = "A:a:Cc:D:g:h:Lo:n:O:p:s:S:T:t:Vv:WzZ:?";

    gettimeofday(&origin, NULL);
    __pmSetProgname(argv[0]);
    QApplication a(argc, argv);
    setupEnvironment();
    readSettings();

    fromsec(globalSettings.chartDelta, &delta);

    tab = new Tab;
    liveGroup = new GroupControl();
    archiveGroup = new GroupControl();

    while ((c = getopt(argc, argv, options)) != EOF) {
      switch (c) {

      case 'A':   /* sample alignment */
          Aflag = optarg;
          break;

      case 'a':
          archives.append(optarg);
          break;

      case 'C':
          Cflag++;
          break;

      case 'c':
          configs.append(optarg);
          break;

      case 'D':
          sts = __pmParseDebug(optarg);
          if (sts < 0) {
            pmprintf("%s: unrecognized debug flag specification (%s)\n",
                  pmProgname, optarg);
            errflg++;
          } else
            pmDebug |= sts;
          break;

      case 'h':
          hosts.append(optarg);
          break;

      case 'g':
          outgeometry = optarg;
          break;

#ifdef PM_USE_CONTEXT_LOCAL
      case 'L':         /* local context */
          Lflag = 1;
          break;
#endif

      case 'n':         /* alternative PMNS */
          pmnsfile = optarg;
          break;

      case 'o':         /* output image file */
          outfile = optarg;
          break;

      case 'O':         /* sample offset */
          Oflag = optarg;
          break;

      case 'p':         /* existing pmtime port */
          port = (int)strtol(optarg, &endnum, 10);
          if (*endnum != '\0' || c < 0) {
            pmprintf("%s: -p requires a numeric argument\n", pmProgname);
            errflg++;
          }
          break;

      case 's':         /* sample history */
          sh = (int)strtol(optarg, &endnum, 10);
          if (*endnum != '\0' || sh < 1) {
            pmprintf("%s: -s requires a numeric argument, larger than 1\n",
                   pmProgname);
            errflg++;
          }
          break;

      case 'S':         /* start run time */
          Sflag = optarg;
          break;

      case 't':         /* sampling interval */
          if (pmParseInterval(optarg, &delta, &msg) < 0) {
            pmprintf("%s: cannot parse interval\n%s", pmProgname, msg);
            free(msg);
            errflg++;
          }
          break;

      case 'T':         /* run time */
          Tflag = optarg;
          break;

      case 'W':         /* white image background */
          Wflag = 1;
          break;

      case 'v':         /* vertical history */
          vh = (int)strtol(optarg, &endnum, 10);
          if (*endnum != '\0' || vh < 1) {
            pmprintf("%s: -v requires a numeric argument, larger than 1\n",
                   pmProgname);
            errflg++;
          }
          break;

      case 'V':         /* version */
          printf("%s %s\n", pmProgname, VERSION);
          exit(0);

      case 'z':         /* timezone from host */
          if (tz != NULL) {
            pmprintf("%s: at most one of -Z and/or -z allowed\n",
                  pmProgname);
            errflg++;
          }
          zflag++;
          break;

      case 'Z':         /* $TZ timezone */
          if (zflag) {
            pmprintf("%s: at most one of -Z and/or -z allowed\n",
                  pmProgname);
            errflg++;
          }
          tz = optarg;
          break;

      case '?':
      default:
          usage();
      }
    }

    if (archives.size() > 0)
      while (optind < argc)
          archives.append(argv[optind++]);
    else
      while (optind < argc)
          hosts.append(argv[optind++]);

    if (optind != argc)
      errflg++;
    if (errflg)
      usage();

    console = new Console(origin);

    //
    // Deal with user requested sample/visible points globalSettings.  These
    // (command line) override the QSettings values, for this instance
    // of pmchart.  They should not be written though, unless requested
    // later via the Settings dialog.
    //
    if (vh != -1 || sh != -1) {
      if (sh == -1)
          sh = globalSettings.sampleHistory;
      if (vh == -1)
          vh = globalSettings.visibleHistory;
      checkHistory(sh, vh);
      if (globalSettings.sampleHistoryModified ||
          globalSettings.visibleHistoryModified) {
          pmprintf("%s: invalid sample/visible history\n", pmProgname);
          pmflush();
          exit(1);
      }
      globalSettings.sampleHistory = sh;
      globalSettings.visibleHistory = vh;
    }
    console->post("Global settings setup complete");

    if (pmnsfile && (sts = pmLoadNameSpace(pmnsfile)) < 0) {
      pmprintf("%s: %s\n", pmProgname, pmErrStr(sts));
      pmflush();
      exit(1);
    }

    // Create all of the sources
    if (Lflag)
      liveGroup->use(PM_CONTEXT_LOCAL, QmcSource::localHost);
    for (c = 0; c < hosts.size(); c++) {
      if (liveGroup->use(PM_CONTEXT_HOST, hosts[c]) < 0)
          hosts.removeAt(c);
    }
    for (c = 0; c < archives.size(); c++) {
      if (archiveGroup->use(PM_CONTEXT_ARCHIVE, archives[c]) < 0)
          archives.removeAt(c);
    }
    if (!Lflag && hosts.size() == 0 && archives.size() == 0)
      liveGroup->createLocalContext();
    pmflush();
    console->post("Metric group setup complete (%d hosts, %d archives)",
                  hosts.size(), archives.size());

    if (zflag) {
      if (archives.size() > 0)
          archiveGroup->useTZ();
      if (hosts.size() > 0)
          liveGroup->useTZ();
    }
    else if (tz != NULL) {
      if (archives.size() > 0)
          archiveGroup->useTZ(QString(tz));
      if (hosts.size() > 0)
          liveGroup->useTZ(QString(tz));
      if ((sts = pmNewZone(tz)) < 0) {
          pmprintf("%s: cannot set timezone to \"%s\": %s\n",
                pmProgname, (char *)tz, pmErrStr(sts));
          pmflush();
          exit(1);
      }
    }

    //
    // Choose which Tab will be displayed initially - archive/live.
    // If any archives given on command line, we go Archive mode;
    // otherwise Live mode wins.  Our initial pmtime connection is
    // set in that mode too.  Later we'll make a second connection
    // in the other mode (and only "on-demand").
    //
    if (archives.size() > 0) {
      archiveGroup->defaultTZ(tzLabel, tzString);
      archiveGroup->updateBounds();
      logStartTime = archiveGroup->logStart();
      logEndTime = archiveGroup->logEnd();
      if ((sts = pmParseTimeWindow(Sflag, Tflag, Aflag, Oflag,
                             &logStartTime, &logEndTime,
                             &realStartTime, &realEndTime,
                             &position, &msg)) < 0) {
          pmprintf("Cannot parse archive time window\n%s\n", msg);
          free(msg);
          usage();
      }
      // move position to account for initial visible points
      if (tcmp(&position, &realStartTime) <= 0)
          for (c = 0; c < globalSettings.visibleHistory - 2; c++)
            tadd(&position, &delta);
      if (tcmp(&position, &realEndTime) > 0)
          position = realEndTime;
    }
    else {
      liveGroup->defaultTZ(tzLabel, tzString);
      gettimeofday(&logStartTime, NULL);
      logEndTime.tv_sec = logEndTime.tv_usec = INT_MAX;
      if ((sts = pmParseTimeWindow(Sflag, Tflag, Aflag, Oflag,
                              &logStartTime, &logEndTime,
                              &realStartTime, &realEndTime,
                              &position, &msg)) < 0) {
          pmprintf("Cannot parse live time window\n%s\n", msg);
          free(msg);
          usage();
      }
    }
    console->post("Timezones and time window setup complete");

    globalFont = QFont("Sans Serif", PmChart::defaultFontSize());
    fileIconProvider = new FileIconProvider();
    pmchart = new PmChart;
    pmtime = new TimeControl;
    console->post("Phase1 user interface constructors complete");

    // Start pmtime process for time management
    pmtime->init(port, archives.size() == 0, &delta, &position,
             &realStartTime, &realEndTime, tzString, tzLabel);

    pmchart->init();
    liveGroup->init(globalSettings.sampleHistory,
                  globalSettings.visibleHistory,
                  pmtime->liveInterval(), pmtime->livePosition());
    archiveGroup->init(globalSettings.sampleHistory,
                  globalSettings.visibleHistory,
                  pmtime->archiveInterval(), pmtime->archivePosition());

    //
    // We setup the pmchart tab list late, so we don't have to deal
    // with kmtime messages reaching the Tabs until we're all setup.
    //
    if (archives.size() == 0)
      tab->init(pmchart->tabWidget(), liveGroup, "Live");
    else
      tab->init(pmchart->tabWidget(), archiveGroup, "Archive");
    pmchart->tabWidget()->insertTab(tab);
    pmchart->setActiveTab(0, true);
    console->post("Phase2 user interface setup complete");

    readSchemes();
    for (c = 0; c < configs.size(); c++)
      OpenViewDialog::openView((const char *)configs[c].toAscii());
    setupViewGlobals();

    if (Cflag)    // done with -c config, quit
      return 0;

    pmchart->enableUi();
    pmchart->show();
    console->post("Top level window shown");

    a.connect(&a, SIGNAL(lastWindowClosed()), pmchart, SLOT(quit()));
    return a.exec();
}

Generated by  Doxygen 1.6.0   Back to index