123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610 |
- #include <QFileDialog>
- #include <QDesktopServices>
- #include <QUrl>
- #include <QMessageBox>
- #include <QFileInfo>
- #include <QFile>
- #include <QTimer>
- #include <QDebug>
- #include <QSettings>
- #include <QInputDialog>
- #include "mainwindow.h"
- #include "ui_mainwindow.h"
- #include "defines.h"
- #include "generatorfileoutput.h"
- #include "settingsdialog.h"
- #include "common/networksettingsdialog.h"
- #include "settings.h"
- #include "rcsession.h"
- #include "qtprojectgeneratorfactory.h"
- #include "symbian/symbiandefines.h" // TODO this should be removed eventually
- MainWindow::MainWindow(QWidget *parent) :
- QMainWindow(parent),
- ui(new Ui::MainWindow),
- m_generator(NULL),
- m_statusUpdater(NULL),
- m_rcSession(NULL)
- {
- ui->setupUi(this);
- // Init variables
- m_buildEnabled = false;
- m_rebuildEnabled = false;
- // Remote generator
- // TODO: no more acting as a server, this can be moved out from here
- m_remote = new RemoteGenerator(this);
- // Init log file. UI progress bar is tied to log file updates.
- m_outputView = new GeneratorFileOutput(Settings::get(Settings::LogFilePath).toString());
- m_rcSession = new RcSession(*m_outputView,
- this);
- buildPlatformsMenu();
- // Init status bar with a progress bar
- m_statusBarLabel = new QLabel(this);
- m_statusBarLabel->setText(tr("Idle"));
- statusBar()->addWidget(m_statusBarLabel, 1);
- m_progressBar = new QProgressBar(this);
- m_progressBar->setVisible(false);
- m_progressBar->setRange(0, m_statusUpdater->maximumProgress());
- m_progressBar->setValue(0);
- statusBar()->addWidget(m_progressBar, 1);
- // Set icons. These are LGPL and *have* to be loaded at run-time!
- // Using LGPL compiled in the binary (i.e. Qt resource file) would risk causing
- // the whole binary to be LGPL. The current icon set is from Oxygen Project,
- // licensed under LGPL v3.
- ui->actionOpenSettings->setIcon(QIcon("oxygen-icons/configure.svgz"));
- ui->actionConnectToRemoteCompiler->setIcon(QIcon("oxygen-icons/network-wired.svgz"));
- ui->actionCloseProject->setIcon(QIcon("oxygen-icons/document-close.svgz"));
- ui->actionOpenWidgetFile->setIcon(QIcon("oxygen-icons/document-open.svgz"));
- ui->actionOpenURL->setIcon(QIcon("oxygen-icons/document-open-remote.svgz"));
- ui->actionOpenDirectory->setIcon(QIcon("oxygen-icons/document-open-folder.svgz"));
- ui->actionPreview->setIcon(QIcon("oxygen-icons/document-preview.svgz"));
- ui->actionBuild->setIcon(QIcon("oxygen-icons/run-build.svgz"));
- ui->actionRebuild->setIcon(QIcon("oxygen-icons/run-build-install.svgz"));
- // Prepare menu selected states
- ui->actionEnableTextSelection->setChecked(Settings::get(Settings::TextSelectionEnabled).toBool());
- ui->actionWidgetIsPannable->setChecked(Settings::get(Settings::PanningEnabled).toBool());
- // UI signals connected to slots
- connect(ui->actionExit, SIGNAL(triggered()), this, SLOT(exitApplication()));
- connect(ui->actionOpenWidgetFile, SIGNAL(triggered()), this, SLOT(openWidgetFile()));
- connect(ui->actionOpenDirectory, SIGNAL(triggered()), this, SLOT(openHTMLDirectory()));
- connect(ui->actionAbout, SIGNAL(triggered()), this, SLOT(about()));
- connect(ui->actionOpenDocumentation, SIGNAL(triggered()), this, SLOT(openDocumentation()));
- connect(ui->actionCloseProject, SIGNAL(triggered()), this, SLOT(closeProject()));
- connect(ui->actionPreview, SIGNAL(triggered()), this, SLOT(preview()));
- connect(ui->actionBuild, SIGNAL(triggered()), this, SLOT(build()));
- connect(ui->actionRebuild, SIGNAL(triggered()), this, SLOT(rebuild()));
- connect(ui->actionWidgetIsPannable, SIGNAL(triggered(bool)), this, SLOT(setPanningEnabled(bool)));
- connect(ui->actionEnableTextSelection, SIGNAL(triggered(bool)), this, SLOT(setTextSelectionEnabled(bool)));
- connect(ui->actionOpenSettings, SIGNAL(triggered()), this, SLOT(openSettingsDialog()));
- connect(ui->actionConnectToRemoteCompiler, SIGNAL(triggered()), this, SLOT(connectToRemoteCompiler()));
- connect(ui->buttonOpenLog, SIGNAL(clicked()), this, SLOT(openLogFile()));
- connect(ui->buttonOpenDirectory, SIGNAL(clicked()), this, SLOT(openBuildDirectory()));
- connect(ui->buttonInstallSis, SIGNAL(clicked()), this, SLOT(installSis()));
- connect(ui->actionOpenURL, SIGNAL(triggered()), this, SLOT(openURL()));
- connect(m_rcSession,
- SIGNAL(refreshRcPropertiesCompleted(bool, bool)),
- this,
- SLOT(rcPropertiesRefreshedSlot(bool, bool)));
- // At startup, there are no projects open
- closeProject();
- checkSettings();
- }
- MainWindow::~MainWindow()
- {
- delete ui;
- delete m_generator;
- m_generator = 0;
- delete m_statusUpdater;
- m_statusUpdater = 0;
- delete m_outputView;
- m_outputView = 0;
- }
- /**
- * Change event handler
- */
- void MainWindow::changeEvent(QEvent *e)
- {
- QMainWindow::changeEvent(e);
- switch (e->type()) {
- case QEvent::LanguageChange:
- ui->retranslateUi(this);
- break;
- default:
- break;
- }
- }
- /**
- * Closes the application
- */
- void MainWindow::exitApplication()
- {
- QCoreApplication::exit(0);
- }
- /**
- * Gives the user a dialog that is used to select a file
- */
- void MainWindow::openWidgetFile()
- {
- QString lastPath = Settings::get(Settings::LastWidgetPath).toString();
- QString fileName = QFileDialog::getOpenFileName(this, tr("Select Widget File"), lastPath, tr("Widget Files") + " (*.wgz *.wgt);;" + tr("All Files (*)"));
- if (!fileName.isEmpty())
- {
- closeProject();
- Settings::set(Settings::LastWidgetPath, QDir::toNativeSeparators(QFileInfo(fileName).absolutePath()));
- setActivePath(fileName);
- }
- }
- /**
- * Gives the user a dialog requesting URL to be fetched
- */
- void MainWindow::openURL()
- {
- QUrl url = QUrl::fromUserInput(QInputDialog::getText(this, tr("Give URL"), "Give URL of the page to be fetched:"));
- if (url.isValid())
- {
- closeProject();
- connect(m_remote, SIGNAL(message(QString)), m_outputView, SLOT(printOutput(QString)));
- connect(m_remote, SIGNAL(finished()), this, SLOT(remoteContentFetched()));
- m_progressBar->setRange(0, 0);
- m_statusBarLabel->setVisible(false);
- m_progressBar->setVisible(true);
- ui->labelStatusValue->setText("Fetching " + url.toString());
- m_remote->getPage(url.toString(), url.host());
- }
- else if (!url.isEmpty())
- {
- QMessageBox::critical(this, tr("Invalid URL"), tr("The given URL is not valid."));
- }
- }
- /**
- * Remote content fetch is finished, reflect in the UI
- */
- void MainWindow::remoteContentFetched()
- {
- m_progressBar->setRange(0, m_statusUpdater->maximumProgress());
- m_progressBar->setValue(m_statusUpdater->maximumProgress());
- ui->labelStatusValue->setText(tr("Content fetch done"));
- }
- /**
- * Gives the user a dialog that is used to select a directory
- */
- void MainWindow::openHTMLDirectory()
- {
- QString lastPath = Settings::get(Settings::LastDirectoryPath).toString();
- QString directoryName = QFileDialog::getExistingDirectory(this, tr("Select HTML Directory. The application will be generated from the contents of the selected directory."), lastPath);
- if (!directoryName.isEmpty())
- {
- closeProject();
- Settings::set(Settings::LastDirectoryPath, QDir::toNativeSeparators(directoryName));
- setActivePath(directoryName);
- }
- }
- /**
- * Sets the path to the opened file/directory. This will be called
- * also from the remote generator.
- */
- void MainWindow::setActivePath(QString path)
- {
- m_currentFileOrDirectory = path;
- ui->labelProjectValue->setText(QDir::toNativeSeparators(path));
- setBuildActionsEnabled(true);
- }
- /**
- * Opens a pre-defined URL in a system's preferred browser
- */
- void MainWindow::openDocumentation()
- {
- QString documentation = "HAG User Guide.pdf";
- if (!QFile::exists(documentation))
- {
- // PDF does not exist any more
- QMessageBox::critical(this, "Documentation not found", "Documentation file was not found! Please reinstall application.");
- }
- else
- {
- // Just presume the user has a PDF viewer installed
- QDesktopServices::openUrl(QUrl::fromLocalFile(documentation));
- }
- }
- /**
- * Calls the SIS, and if the user has PC Suite installed, it will
- * prompt the installation
- */
- void MainWindow::installSis()
- {
- QFileInfo
- pkgFile = m_statusUpdater->pkgFileInfo();
- IQtProjectGenerator::PkgInstallResult
- result = m_generator->installPkg(pkgFile);
- // TODO maybe some action about supportedness / success
- Q_UNUSED(result)
- }
- /**
- * Shows "about" message box
- */
- void MainWindow::about()
- {
- QMessageBox aboutBox;
- QPixmap pixmap(":/gfx/qt.svg");
- pixmap = pixmap.scaled(QSize(100, 100), Qt::KeepAspectRatio, Qt::SmoothTransformation);
- aboutBox.setIconPixmap(pixmap);
- aboutBox.setWindowTitle(tr("About Hybrid Application Generator"));
- aboutBox.setText(tr("Hybrid Application Generator 0.1"));
- aboutBox.setInformativeText("Built on Apr 14 2010\n\nCopyright 2009-2010 Nokia Corporation. All rights reserved.\n\nThe program is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.");
- aboutBox.setStyleSheet("#qt_msgbox_label { font-weight: bold; font-size: 10pt; }");
- aboutBox.exec();
- }
- void MainWindow::platformChosen()
- {
- QAction
- * action = qobject_cast<QAction*>(sender());
- if (action != NULL)
- {
- QString
- platformId = action->data().toString();
- setPlatform(platformId);
- m_progressBar->setRange(0, m_statusUpdater->maximumProgress());
- m_progressBar->setValue(0);
- }
- }
- /**
- * Enable actions that are directly related to a widget only if a
- * widget is currectly open
- */
- void MainWindow::setBuildActionsEnabled(bool enabled)
- {
- // Set new value buildEnabled; rebuildEnabled also has
- // to be allowed beforehand to be allowed now
- m_buildEnabled = enabled;
- m_rebuildEnabled = m_rebuildEnabled && m_buildEnabled;
- if (enabled == false)
- {
- ui->labelStatusValue->setText(tr("Idle"));
- m_statusBarLabel->setText(tr("Idle"));
- ui->labelLogValue->setText(tr("<no log available>"));
- ui->buttonOpenDirectory->setEnabled(false);
- ui->buttonInstallSis->setEnabled(false);
- m_progressBar->setVisible(false);
- m_statusBarLabel->setVisible(true);
- }
- // Check that settings allow building
- checkSettings();
- // Actions are enabled only when a project is open
- ui->actionCloseProject->setEnabled(enabled);
- }
- /**
- * Closes the project, i.e. clear selected file and disables
- * relevant menu items.
- */
- void MainWindow::closeProject()
- {
- m_generator->closeProject();
- m_currentFileOrDirectory = "";
- ui->labelProjectValue->setText(tr("<no file selected>"));
- setBuildActionsEnabled(false);
- }
- /**
- * If the selected file / folder still exists, prepares the necessary
- * folder structure and opens an external application that shows the
- * widget-to-be in a window that is sized to match device resolution
- */
- void MainWindow::preview()
- {
- // Check that file exists
- if (QFile::exists(m_currentFileOrDirectory))
- {
- m_generator->preview(m_currentFileOrDirectory);
- }
- }
- /**
- * Extract, prepare, and build the selected file / folder
- */
- void MainWindow::build()
- {
- m_generator->build(m_currentFileOrDirectory,
- *m_rcSession);
- }
- /**
- * Rebuild without cleaning the target folder structure first.
- * Can be used to keep changes if e.g. widget content is changed
- * directly in the build directory -- otherwise the target would
- * be deleted and replaced with fresh source files.
- */
- void MainWindow::rebuild()
- {
- m_generator->rebuild(*m_rcSession);
- }
- /**
- * Enables / disables the option to enable panning canvas in widgets
- */
- void MainWindow::setPanningEnabled(bool enabled)
- {
- Settings::set(Settings::PanningEnabled, enabled);
- }
- /**
- * Enables / disables the option to disable text selection in widgets
- */
- void MainWindow::setTextSelectionEnabled(bool enabled)
- {
- Settings::set(Settings::TextSelectionEnabled, enabled);
- }
- /**
- * Update the UI when the generation progresses
- */
- void MainWindow::progressUpdated()
- {
- m_statusBarLabel->setVisible(false);
- m_progressBar->setVisible(true);
- m_progressBar->setValue(m_statusUpdater->currentProgress());
- ui->labelStatusValue->setText(m_statusUpdater->statusText());
- ui->labelLogValue->setText(tr("Logged") + " " + QString::number(m_statusUpdater->logSize()) + " " + tr("rows"));
- }
- /**
- * When the generation progress is done, update the UI
- * to reflect the completed state
- */
- void MainWindow::progressFinished(bool success)
- {
- m_rebuildEnabled = m_buildEnabled;
- ui->actionRebuild->setEnabled(m_buildEnabled);
- ui->buttonOpenDirectory->setEnabled(true);
- if (success && m_generator->getTarget() == BUILD)
- {
- ui->buttonInstallSis->setEnabled(true);
- }
- }
- /**
- * Opens the log file in an external viewer.
- */
- void MainWindow::openLogFile()
- {
- QDesktopServices::openUrl(QUrl::fromLocalFile(Settings::get(Settings::LogFilePath).toString()));
- }
- /**
- * Opens the settings dialog that has further configurations
- */
- void MainWindow::openSettingsDialog()
- {
- SettingsDialog
- sd(m_generator,
- m_currentFileOrDirectory,
- this);
- sd.exec();
- checkSettings();
- }
- /**
- * Opens the network settings dialog.
- */
- void MainWindow::connectToRemoteCompiler()
- {
- NetworkSettingsDialog
- nsd(m_rcSession,
- this);
- nsd.exec();
- if (nsd.justSignedIn())
- {
- m_rcSession->refreshRcProperties();
- }
- checkSettings();
- }
- /**
- * Check settings that has to be correct before building can proceed.
- */
- void MainWindow::checkSettings()
- {
- QStringList
- errors = m_generator->errorsForTarget(BUILD);
- if (errors.empty())
- {
- ui->labelBuildValue->setText(Settings::get(Settings::QtVersionString).toString());
- ui->labelSettingsValue->setStyleSheet("");
- ui->labelSettingsValue->setText("Settings OK");
- }
- else
- {
- ui->labelBuildValue->setText("<not available>");
- ui->labelSettingsValue->setStyleSheet("QLabel { color: red; }");
- ui->labelSettingsValue->setText(errors.at(0));
- }
- // The preview Qt version is the version with which the generator is compiled
- ui->labelPreviewValue->setText("4.6.2");
- // Settings affect the building: disable if qtenv.bat is not configured
- ui->actionPreview->setEnabled(m_buildEnabled && errors.empty());
- ui->actionBuild->setEnabled(m_buildEnabled && errors.empty());
- ui->actionRebuild->setEnabled(m_rebuildEnabled && errors.empty());
- }
- void MainWindow::setPlatform(QString platformId)
- {
- if (platformId != m_platformId || m_generator == NULL)
- {
- delete m_generator;
- m_generator = 0;
- delete m_statusUpdater;
- m_statusUpdater = 0;
- m_platformId = platformId;
- QtProjectGeneratorFactory
- generatorFactory;
- m_generator = generatorFactory.createProjectGenerator(m_platformId,
- *m_outputView,
- NULL); // parent
- // Status updater
- m_statusUpdater = m_generator->createStatusUpdater(NULL); // parent
- connect(m_statusUpdater, SIGNAL(updated()), this, SLOT(progressUpdated()));
- connect(m_statusUpdater, SIGNAL(finished(bool)), this, SLOT(progressFinished(bool)));
- setActivePath(m_currentFileOrDirectory);
- }
- }
- void MainWindow::openBuildDirectory()
- {
- QDesktopServices::openUrl(QUrl::fromLocalFile(m_generator->generatorData().projectDirectory()));
- }
- void MainWindow::rcPropertiesRefreshedSlot(bool success,
- bool hasRcPropertiesChanged)
- {
- if (success)
- {
- if (hasRcPropertiesChanged)
- {
- buildPlatformsMenu();
- QMessageBox::information(this,
- "Connecting Remote Compiler Succeeded",
- "Please check build menu for potential\n"
- "new remote build targets",
- QMessageBox::Ok);
- }
- }
- else
- {
- QMessageBox::warning(this,
- "Remote Compiler Request Failed",
- "Querying Remote Compiler for supporter OS/QT platforms failed.",
- QMessageBox::Ok);
- }
- }
- void MainWindow::buildPlatformsMenu()
- {
- // we clear up the build menu after the second separator
- QObjectList
- buildMenuKids = ui->menuBuild->children();
- foreach (QObject * kid, buildMenuKids)
- {
- QAction
- * kidAction = qobject_cast<QAction*>(kid);
- if (kidAction == NULL)
- continue;
- if (kidAction->data().toString().indexOf(DYN_BUILDTARGET) == 0)
- {
- ui->menubar->removeAction(kidAction);
- delete kidAction;
- }
- }
- // Getting platform infos, and building menu items & actions for them
- QList<QAction*>
- platformActions;
- QString
- defaultPlatformId;
- QtProjectGeneratorFactory
- generatorFactory;
- QList<PlatformInfo>
- platformInfos = generatorFactory.supportedPlatforms();
- QList<PlatformInfo>::const_iterator
- piIt = platformInfos.begin(),
- piEnd = platformInfos.end();
- for (; piIt != piEnd; ++piIt)
- {
- QAction
- * action = new QAction(piIt->m_platformName,
- ui->menuBuild);
- action->setData(piIt->m_platformId);
- action->setCheckable(true);
- // OBS action->setStatusTip(tr("Choose platform to build for"));
- action->setStatusTip(piIt->m_shortDescription);
- connect(action,
- SIGNAL(triggered()),
- this,
- SLOT(platformChosen()));
- platformActions.push_back(action);
- if (piIt->m_isDefault)
- {
- action->setChecked(true);
- defaultPlatformId = piIt->m_platformId;
- }
- }
- // QActionGroup makes these platform menu items behave like "radio buttons"
- // only one can be selected at a time
- QActionGroup
- * platformActionGroup = new QActionGroup(this);
- QList<QAction*>::const_iterator
- paIt = platformActions.begin(),
- paEnd = platformActions.end();
- for (; paIt != paEnd; ++paIt)
- platformActionGroup->addAction(*paIt);
- // Adding actions to the "build" menu
- paIt = platformActions.begin(),
- paEnd = platformActions.end();
- for (; paIt != paEnd; ++paIt)
- ui->menuBuild->addAction(*paIt);
- // setting the default platform name (and m_generator and m_statusUpdater
- // instances accordingly)
- setPlatform(defaultPlatformId);
- }
|