From da1e965c83e78300643948bbdffe9392625ef135 Mon Sep 17 00:00:00 2001 From: xavierqet Date: Sat, 26 Jul 2008 15:26:19 +0000 Subject: [PATCH] L'application est desormais capable d'ouvrir un fichier element passe en parametre git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@357 bfdf4180-ca20-0410-9c96-a3a8aa849046 --- qelectrotech.pro | 2 + qet.cpp | 52 +++++++++ qet.h | 4 + qetapp.cpp | 105 ++++++++++-------- qetapp.h | 8 +- qetarguments.cpp | 272 +++++++++++++++++++++++++++++++++++++++++++++++ qetarguments.h | 81 ++++++++++++++ 7 files changed, 476 insertions(+), 48 deletions(-) create mode 100644 qetarguments.cpp create mode 100644 qetarguments.h diff --git a/qelectrotech.pro b/qelectrotech.pro index e392762e3..6a703aba0 100644 --- a/qelectrotech.pro +++ b/qelectrotech.pro @@ -77,6 +77,7 @@ HEADERS += aboutqet.h \ orientationsetwidget.h \ qet.h \ qetapp.h \ + qetarguments.h \ qetdiagrameditor.h \ qetsingleapplication.h \ qgimanager.h \ @@ -144,6 +145,7 @@ SOURCES += aboutqet.cpp \ orientationsetwidget.cpp \ qet.cpp \ qetapp.cpp \ + qetarguments.cpp \ qetdiagrameditor.cpp \ qetsingleapplication.cpp \ qgimanager.cpp \ diff --git a/qet.cpp b/qet.cpp index 80c3a6cd1..93d66ab5c 100644 --- a/qet.cpp +++ b/qet.cpp @@ -238,3 +238,55 @@ bool QET::containsForbiddenCharacters(const QString &string) { } return(false); } + +/** + @param string une chaine de caracteres + @return la meme chaine de caracteres, mais avec les espaces et backslashes + echappes +*/ +QString QET::escapeSpaces(const QString &string) { + return(QString(string).replace('\\', "\\\\").replace(' ', "\\ ")); +} + +/** + @param string une chaine de caracteres + @return la meme chaine de caracteres, mais avec les espaces et backslashes + non echappes +*/ +QString QET::unescapeSpaces(const QString &string) { + return(QString(string).replace("\\\\", "\\").replace("\\ ", " ")); +} + +/** + Assemble une liste de chaines en une seule. Un espace separe chaque chaine. + Les espaces et backslashes des chaines sont echappes. + @param string_list une liste de chaine + @return l'assemblage des chaines +*/ +QString QET::joinWithSpaces(const QStringList &string_list) { + QString returned_string; + + for (int i = 0 ; i < string_list.count() ; ++ i) { + returned_string += QET::escapeSpaces(string_list.at(i)); + if (i != string_list.count() - 1) returned_string += " "; + } + + return(returned_string); +} + +/** + @param string Une chaine de caracteres contenant des sous-chaines a + extraire separees par des espaces non echappes. Les espaces des sous-chaines + sont echappes. + @return La liste des sous-chaines, sans echappement. +*/ +QStringList QET::splitWithSpaces(const QString &string) { + // les chaines sont separees par des espaces non echappes = avec un nombre nul ou pair de backslashes devant + QStringList escaped_strings = string.split(QRegExp("[^\\]?(?:\\\\)* "), QString::SkipEmptyParts); + + QStringList returned_list; + foreach(QString escaped_string, escaped_strings) { + returned_list << QET::unescapeSpaces(escaped_string); + } + return(returned_list); +} diff --git a/qet.h b/qet.h index cc91ce145..0bd8d0ec6 100644 --- a/qet.h +++ b/qet.h @@ -44,5 +44,9 @@ namespace QET { QList findInDomElement(const QDomElement &, const QString &, const QString &); QList forbiddenCharacters(); bool containsForbiddenCharacters(const QString &); + QString escapeSpaces(const QString &); + QString unescapeSpaces(const QString &); + QString joinWithSpaces(const QStringList &); + QStringList splitWithSpaces(const QString &); } #endif diff --git a/qetapp.cpp b/qetapp.cpp index d11b901d8..17bd553d9 100644 --- a/qetapp.cpp +++ b/qetapp.cpp @@ -41,11 +41,11 @@ QETApp::QETApp(int &argc, char **argv) : initConfiguration(); if (!non_interactive_execution_ && isRunning()) { - QStringList abs_arg_list(arguments_options_); - abs_arg_list << arguments_files_; - // envoie les arguments a l'instance deja existante - non_interactive_execution_ = sendMessage("launched-with-args: " + abs_arg_list.join(" ")); + non_interactive_execution_ = sendMessage( + "launched-with-args: " + + QET::joinWithSpaces(QStringList(qet_arguments_.arguments())) + ); } if (non_interactive_execution_) { @@ -67,8 +67,12 @@ QETApp::QETApp(int &argc, char **argv) : setQuitOnLastWindowClosed(false); connect(this, SIGNAL(lastWindowClosed()), this, SLOT(checkRemainingWindows())); - // Creation et affichage d'un editeur de schema - new QETDiagramEditor(arguments_files_); + // on ouvre soit les fichiers passes en parametre soit un nouvel editeur de projet + if (qet_arguments_.files().isEmpty()) { + new QETDiagramEditor(); + } else { + openFiles(qet_arguments_); + } buildSystemTrayMenu(); } @@ -454,20 +458,31 @@ void QETApp::checkRemainingWindows() { void QETApp::messageReceived(const QString &message) { if (message.startsWith("launched-with-args: ")) { QString my_message(message.mid(20)); - QStringList files_list = my_message.split(' '); - openFiles(files_list); + // les arguments sont separes par des espaces non echappes + QStringList args_list = QET::splitWithSpaces(my_message); + openFiles(QETArguments(args_list)); } } +/** + Ouvre les fichiers passes en arguments + @param args Objet contenant des arguments ; les fichiers + @see openProjectFiles openElementFiles +*/ +void QETApp::openFiles(const QETArguments &args) { + openProjectFiles(args.projectFiles()); + openElementFiles(args.elementFiles()); +} + /** Ouvre une liste de fichiers. Les fichiers sont ouverts dans le premier editeur de schemas visible venu. Sinon, le premier editeur de schemas existant venu devient visible et est utilise. S'il n'y a aucun editeur de schemas ouvert, un nouveau est cree et utilise. - @param files_list Liste des fichiers a ouvrir + @param files Fichiers a ouvrir */ -void QETApp::openFiles(const QStringList &files_list) { +void QETApp::openProjectFiles(const QStringList &files_list) { if (files_list.isEmpty()) return; // liste des editeurs de schema ouverts @@ -499,6 +514,21 @@ void QETApp::openFiles(const QStringList &files_list) { } } +/** + Ouvre les fichiers elements passes en parametre. Si un element est deja + ouvert, la fentre qui l'edite est activee. + @param files Fichiers a ouvrir +*/ +void QETApp::openElementFiles(const QStringList &files_list) { + if (files_list.isEmpty()) return; + + // creation et affichage d'un ou plusieurs editeurs d'element + foreach(QString element_file, files_list) { + QETElementEditor *element_editor = new QETElementEditor(); + element_editor -> fromFile(element_file); + } +} + /** @param window fenetre dont il faut trouver les barres d'outils et dock flottants @return les barres d'outils et dock flottants de la fenetre @@ -533,46 +563,31 @@ void QETApp::parseArguments() { // enleve le premier argument : il s'agit du fichier binaire arguments_list.takeFirst(); - // separe les fichiers des options - foreach(QString argument, arguments_list) { - QFileInfo argument_info(argument); - if (argument_info.exists()) { - // on exprime les chemins des fichiers en absolu - arguments_files_ << argument_info.canonicalFilePath(); - } else { - arguments_options_ << argument; - } - } + // analyse les arguments + qet_arguments_ = QETArguments(arguments_list); - // parcourt les options - foreach(QString argument, arguments_options_) { #ifdef QET_ALLOW_OVERRIDE_CED_OPTION - QString ced_arg("--common-elements-dir="); - if (argument.startsWith(ced_arg)) { - QString ced_value = argument.right(argument.length() - ced_arg.length()); - overrideCommonElementsDir(ced_value); - continue; - } + if (qet_arguments_.commonElementsDirSpecified()) { + overrideCommonElementsDir(qet_arguments_.commonElementsDir()); + } #endif #ifdef QET_ALLOW_OVERRIDE_CD_OPTION - QString cd_arg("--config-dir="); - if (argument.startsWith(cd_arg)) { - QString cd_value = argument.right(argument.length() - cd_arg.length()); - overrideConfigDir(cd_value); - continue; - } + if (qet_arguments_.configDirSpecified()) { + overrideConfigDir(qet_arguments_.configDir()); + } #endif - - if (argument == QString("--help")) { - printHelp(); - non_interactive_execution_ = true; - } else if (argument == QString("--version") || argument == QString("-v")) { - printVersion(); - non_interactive_execution_ = true; - } else if (argument == QString("--license")) { - printLicense(); - non_interactive_execution_ = true; - } + + if (qet_arguments_.printLicenseRequested()) { + printLicense(); + non_interactive_execution_ = true; + } + if (qet_arguments_.printHelpRequested()) { + printHelp(); + non_interactive_execution_ = true; + } + if (qet_arguments_.printVersionRequested()) { + printVersion(); + non_interactive_execution_ = true; } } diff --git a/qetapp.h b/qetapp.h index 306785624..1a2529022 100644 --- a/qetapp.h +++ b/qetapp.h @@ -20,6 +20,7 @@ #include "qetsingleapplication.h" #include #include +#include "qetarguments.h" class QETDiagramEditor; class QETElementEditor; /** @@ -99,8 +100,7 @@ class QETApp : public QETSingleApplication { bool every_element_visible; QSignalMapper signal_map; QSettings *qet_settings; - QList arguments_files_; ///< Chemins de fichiers detectes parmi les arguments - QList arguments_options_; ///< Options detectees parmi les arguments + QETArguments qet_arguments_; ///< Analyseur d'arguments bool non_interactive_execution_; ///< booleen indiquant si l'application va se terminer immediatement apres un court traitement static QString diagram_texts_font; @@ -120,7 +120,9 @@ class QETApp : public QETSingleApplication { void quitQET(); void checkRemainingWindows(); void messageReceived(const QString &); - void openFiles(const QStringList &); + void openFiles(const QETArguments &); + void openProjectFiles(const QStringList &); + void openElementFiles(const QStringList &); // methodes privees private slots: diff --git a/qetarguments.cpp b/qetarguments.cpp new file mode 100644 index 000000000..53ed57749 --- /dev/null +++ b/qetarguments.cpp @@ -0,0 +1,272 @@ +#include "qetarguments.h" + +/** + Constructeur par defaut + Cree un objet sans argument. +*/ +QETArguments::QETArguments(QObject *parent) : + QObject(parent), + print_help_(false), + print_license_(false), + print_version_(false) +{ +} + +/** + Constructeur + @param args Arguments a analyser et memoriser + @param parent QObject parent +*/ +QETArguments::QETArguments(const QList &args, QObject *parent) : + QObject(parent), + print_help_(false), + print_license_(false), + print_version_(false) +{ + parseArguments(args); +} + +/** + Constructeur de copie - la copie reprend le parent de l'original + @param qet_arguments Objet a copier +*/ +QETArguments::QETArguments(const QETArguments &qet_arguments) : + QObject(qet_arguments.parent()), + project_files_(qet_arguments.project_files_), + element_files_(qet_arguments.element_files_), + options_(qet_arguments.options_), + unknown_options_(qet_arguments.unknown_options_), + print_help_(qet_arguments.print_help_), + print_license_(qet_arguments.print_license_), + print_version_(qet_arguments.print_version_) +{ +} + +/** + Operateur d'affectation - la copie ne reprend pas le parent de l'original + @param qet_arguments Objet a copier +*/ +QETArguments &QETArguments::operator=(const QETArguments &qet_arguments) { + project_files_ = qet_arguments.project_files_; + element_files_ = qet_arguments.element_files_; + options_ = qet_arguments.options_; + unknown_options_ = qet_arguments.unknown_options_; + print_help_ = qet_arguments.print_help_; + print_license_ = qet_arguments.print_license_; + print_version_ = qet_arguments.print_version_; + return(*this); +} + +/** + Destructeur +*/ +QETArguments::~QETArguments() { +} + +/** + Definit les arguments de cet objet. + Si cet objet contenait deja des arguments, ceux-ci sont oublies. + @param args Arguments a analyser et memoriser +*/ +void QETArguments::setArguments(const QList &args) { + parseArguments(args); +} + +/** + @return tous les arguments (projets et elements) passes en parametres + dans l'ordre suivant : options connues puis inconnues, fichiers de types + projet puis element. +*/ +QList QETArguments::arguments() const { + return(options_ + unknown_options_ + project_files_ + element_files_); +} + +/** + @return tous les fichiers (projets et elements) passes en parametres. + Les fichiers de type projet viennent avant les fichiers de type element. +*/ +QList QETArguments::files() const { + return(project_files_ + element_files_); +} + +/** + @return les fichiers de type projet +*/ +QList QETArguments::projectFiles() const { + return(project_files_); +} + +/** + @return les fichiers de type element +*/ +QList QETArguments::elementFiles() const { + return(element_files_); +} + +/** + @return les options reconnues +*/ +QList QETArguments::options() const { + return(options_); +} + +/** + @return les options non reconnues +*/ +QList QETArguments::unknownOptions() const { + return(unknown_options_); +} + +/** + Oublie tous les arguments de cet objet +*/ +void QETArguments::clear() { + project_files_.clear(); + element_files_.clear(); + options_.clear(); + unknown_options_.clear(); + common_elements_dir_.clear(); + config_dir_.clear(); +} + +/** + Analyse des arguments et les retient dans cet objet. + Si cet objet contenait deja des arguments, ceux-ci sont oublies. + @param args Arguments a analyser +*/ +void QETArguments::parseArguments(const QList &arguments) { + // oublie les eventuels arguments precedents + clear(); + + // separe les fichiers des options + foreach(QString argument, arguments) { + QFileInfo argument_info(argument); + if (argument_info.exists()) { + // on exprime les chemins des fichiers en absolu + QString can_argument = argument_info.canonicalFilePath(); + handleFileArgument(can_argument); + } else { + handleOptionArgument(argument); + } + } +} + +/** + Gere les arguments correspondant a un fichier existant. +*/ +void QETArguments::handleFileArgument(const QString &file) { + if (file.endsWith(".elmt")) { + if (!element_files_.contains(file)) { + element_files_ << file; + } + } else { + if (!project_files_.contains(file)) { + project_files_ << file; + } + } +} + +/** + Gere les arguments correspondant potentiellement a une option. + Les options reconnues sont : + * --common-elements-dir= + * --config-dir + * --help + * --version + * -v + * --license +*/ +void QETArguments::handleOptionArgument(const QString &option) { + if (option == QString("--help")) { + print_help_ = true; + options_ << option; + return; + } else if (option == QString("--version") || option == QString("-v")) { + print_version_ = true; + options_ << option; + return; + } else if (option == QString("--license")) { + print_license_ = true; + options_ << option; + return; + } + +#ifdef QET_ALLOW_OVERRIDE_CED_OPTION + QString ced_arg("--common-elements-dir="); + if (option.startsWith(ced_arg)) { + common_elements_dir_ = option.mid(ced_arg.length()); + return; + } + +#endif +#ifdef QET_ALLOW_OVERRIDE_CD_OPTION + QString cd_arg("--config-dir="); + if (option.startsWith(cd_arg)) { + QString config_dir_ = option.mid(ced_arg.length()); + return; + } + +#endif + + // a ce stade, l'option est inconnue + unknown_options_ << option; +} + +#ifdef QET_ALLOW_OVERRIDE_CED_OPTION +/** + @return true si l'utilisateur a specifie un dossier pour la collection + commune. +*/ +bool QETArguments::commonElementsDirSpecified() const { + return(!common_elements_dir_.isEmpty()); +} + +/** + @return le dossier de la collection commune specifie par l'utilisateur. + Si l'utilisateur n'en a pas specifie, une chaine vide est retournee. +*/ +QString QETArguments::commonElementsDir() const { + return(common_elements_dir_); +} + +#endif +#ifdef QET_ALLOW_OVERRIDE_CD_OPTION +/** + @return true si l'utilisateur a specifie un dossier pour la configuration. +*/ +bool QETArguments::configDirSpecified() const { + return(!config_dir_.isEmpty()); +} + +/** + @return le dossier de configuration specifie par l'utilisateur. + Si l'utilisateur n'en a pas specifie, une chaine vide est retournee. +*/ +QString QETArguments::configDir() const { + return(config_dir_); +} +#endif + +/** + @return true si les arguments comportent une demande d'affichage de l'aide, + false sinon +*/ +bool QETArguments::printHelpRequested() const { + return(print_help_); +} + +/** + @return true si les arguments comportent une demande d'affichage de la + licence, false sinon +*/ +bool QETArguments::printLicenseRequested() const { + return(print_license_); +} + +/** + @return true si les arguments comportent une demande d'affichage de la + version, false sinon +*/ +bool QETArguments::printVersionRequested() const { + return(print_version_); +} diff --git a/qetarguments.h b/qetarguments.h new file mode 100644 index 000000000..2fe741539 --- /dev/null +++ b/qetarguments.h @@ -0,0 +1,81 @@ +/* + Copyright 2006-2008 Xavier Guerrin + This file is part of QElectroTech. + + QElectroTech 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. + + QElectroTech 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 QElectroTech. If not, see . +*/ +#ifndef QET_ARGUMENTS_H +#define QET_ARGUMENTS_H +#include +/** + Cette classe represente un ensemble d'arguments que l'application peut + recevoir en parametres. Initialisee a partir d'une liste de chaine de + caracteres, chaque instance de cette classe permet d'acceder aux differents + types de fichiers et options passes en parametres. +*/ +class QETArguments : public QObject { + Q_OBJECT + + // constructeurs, destructeur + public: + QETArguments(QObject * = 0); + QETArguments(const QList &, QObject * = 0); + QETArguments(const QETArguments &); + QETArguments &operator=(const QETArguments &); + virtual ~QETArguments(); + + // methodes + public: + virtual void setArguments(const QList &); + virtual QList arguments() const; + virtual QList files() const; + virtual QList projectFiles() const; + virtual QList elementFiles() const; +#ifdef QET_ALLOW_OVERRIDE_CED_OPTION + virtual bool commonElementsDirSpecified() const; + virtual QString commonElementsDir() const; +#endif +#ifdef QET_ALLOW_OVERRIDE_CD_OPTION + virtual bool configDirSpecified() const; + virtual QString configDir() const; +#endif + virtual bool printHelpRequested() const; + virtual bool printLicenseRequested() const; + virtual bool printVersionRequested() const; + virtual QList options() const; + virtual QList unknownOptions() const; + + private: + void clear(); + void parseArguments(const QList &); + void handleFileArgument(const QString &); + void handleOptionArgument(const QString &); + + // attributs + private: + QList project_files_; + QList element_files_; + QList options_; + QList unknown_options_; +#ifdef QET_ALLOW_OVERRIDE_CED_OPTION + QString common_elements_dir_; +#endif +#ifdef QET_ALLOW_OVERRIDE_CD_OPTION + QString config_dir_; +#endif + bool print_help_; + bool print_license_; + bool print_version_; +}; +#endif