00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "mainwindow.h"
00025 #include "helpdialog.h"
00026 #include "config.h"
00027
00028 #include <QTcpServer>
00029 #include <QTcpSocket>
00030 #include <QApplication>
00031 #include <QPixmap>
00032 #include <QStringList>
00033 #include <QDir>
00034 #include <QMessageBox>
00035 #include <QPointer>
00036 #include <QTranslator>
00037 #include <QLibraryInfo>
00038 #include <QLocale>
00039 #include <stdlib.h>
00040 #include <stdio.h>
00041
00042 #if defined(USE_STATIC_JPEG_PLUGIN)
00043 #include <QtPlugin>
00044 Q_IMPORT_PLUGIN(qjpeg)
00045 #endif
00046
00047 #define INDEX_CHECK( text ) if( i+1 >= argc ) { fprintf(stderr, "%s\n", text); return 1; }
00048
00049
00050 #if !defined(QT_NO_DBUS) && defined(Q_OS_UNIX)
00051 #include <QtDBus/QDBusConnection>
00052 #include <QtDBus/QDBusAbstractAdaptor>
00053
00054 class AssistantAdaptor : public QDBusAbstractAdaptor
00055 {
00056 Q_OBJECT
00057 Q_CLASSINFO("D-Bus Interface", "com.trolltech.Assistant.HelpViewer")
00058
00059 public:
00060 AssistantAdaptor(MainWindow *mw) : QDBusAbstractAdaptor(mw), mw(mw)
00061 {
00062 QDBusConnection connection = QDBusConnection::sessionBus();
00063 connection.registerService("com.trolltech.Assistant");
00064 connection.registerObject("/Assistant", mw);
00065 }
00066
00067 public slots:
00068 void showLink(const QString &link) { mw->showLink(link); }
00069
00070 private:
00071 MainWindow *mw;
00072 };
00073 #endif // QT_NO_DBUS
00074
00075 class AssistantSocket : public QTcpSocket
00076 {
00077 Q_OBJECT
00078 public:
00079 AssistantSocket( int sock, QObject *parent = 0 );
00080 ~AssistantSocket() {}
00081
00082 signals:
00083 void showLinkRequest( const QString& );
00084
00085 private slots:
00086 void readClient();
00087 void connectionClosed();
00088 };
00089
00090
00091 class AssistantServer : public QTcpServer
00092 {
00093 Q_OBJECT
00094 public:
00095 AssistantServer( QObject* parent = 0 );
00096 quint16 getPort() const;
00097
00098 signals:
00099 void showLinkRequest( const QString& );
00100 void newConnect();
00101
00102 public slots:
00103 virtual void incomingConnection( int socket );
00104
00105 private:
00106 quint16 p;
00107 };
00108
00109 AssistantSocket::AssistantSocket( int sock, QObject *parent )
00110 : QTcpSocket( parent )
00111 {
00112 connect( this, SIGNAL(readyRead()), SLOT(readClient()) );
00113 connect( this, SIGNAL(disconnected()), SLOT(connectionClosed()) );
00114 setSocketDescriptor( sock );
00115 }
00116
00117 void AssistantSocket::readClient()
00118 {
00119 QString link = QString();
00120 while ( canReadLine() )
00121 link = readLine();
00122 if ( !link.isNull() ) {
00123 link = link.replace(QLatin1String("\n"), QLatin1String(""));
00124 link = link.replace(QLatin1String("\r"), QLatin1String(""));
00125 QFileInfo fi(link);
00126 link = fi.absoluteFilePath();
00127 emit showLinkRequest( link );
00128 }
00129 }
00130
00131 void AssistantSocket::connectionClosed()
00132 {
00133 deleteLater();
00134 }
00135
00136 AssistantServer::AssistantServer( QObject *parent )
00137 : QTcpServer( parent )
00138 {
00139 listen(QHostAddress::LocalHost, 0);
00140 if ( !isListening() ) {
00141 QMessageBox::critical( 0, tr( "Qt Assistant" ),
00142 tr( "Failed to bind to port %1" ).arg( serverPort() ) );
00143 exit( 1 );
00144 }
00145 p = serverPort();
00146 }
00147
00148 quint16 AssistantServer::getPort() const
00149 {
00150 return p;
00151 }
00152
00153 void AssistantServer::incomingConnection( int socket )
00154 {
00155 AssistantSocket *as = new AssistantSocket( socket, this );
00156 connect( as, SIGNAL(showLinkRequest(QString)),
00157 this, SIGNAL(showLinkRequest(QString)) );
00158 emit newConnect();
00159 }
00160
00161 int main( int argc, char ** argv )
00162 {
00163 Q_INIT_RESOURCE(assistant);
00164
00165 bool withGUI = true;
00166 #ifndef Q_WS_WIN
00167 if ( argc > 1 ) {
00168 QString arg = QString::fromLocal8Bit(argv[1]);
00169 arg = arg.toLower();
00170 if ( arg == QLatin1String("-addcontentfile")
00171 || arg == QLatin1String("-removecontentfile")
00172 || arg == QLatin1String("-help")
00173 || arg == QLatin1String("/?")
00174 )
00175 withGUI = false;
00176 }
00177 #endif
00178 QApplication a(argc, argv, withGUI);
00179 a.setOrganizationName("Trolltech");
00180 a.setApplicationName("Assistant");
00181
00182 QString resourceDir;
00183 AssistantServer *as = 0;
00184 QStringList catlist;
00185 QString file, profileName, aDocPath;
00186 bool server = false;
00187 bool hideSidebar = false;
00188 if ( argc == 2 ) {
00189 file = QString::fromLocal8Bit(argv[1]);
00190 if (file.startsWith(QLatin1String("-")) || file == QLatin1String("/?")) {
00191 file.clear();
00192 } else {
00193 QFileInfo fi(file);
00194 file = fi.absoluteFilePath();
00195 file = MainWindow::urlifyFileName(file);
00196 }
00197 }
00198 if ( file.isEmpty() ) {
00199 for ( int i = 1; i < argc; i++ ) {
00200 QString opt = QString::fromLocal8Bit(argv[i]).toLower();
00201 if ( opt == QLatin1String("-file") ) {
00202 INDEX_CHECK( "Missing file argument!" );
00203 i++;
00204 file = QFile::decodeName(argv[i]);
00205 } else if ( opt == QLatin1String("-server") ) {
00206 server = true;
00207 } else if ( opt == QLatin1String("-profile") ) {
00208 INDEX_CHECK( "Missing profile argument!" );
00209 profileName = QFile::decodeName(argv[++i]);
00210 } else if ( opt == QLatin1String("-addcontentfile") ) {
00211 INDEX_CHECK( "Missing content file!" );
00212 Config *c = Config::loadConfig(QString());
00213 QFileInfo file( QFile::decodeName(argv[i+1]) );
00214 if( !file.exists() ) {
00215 fprintf(stderr, "Could not locate content file: %s\n", qPrintable(file.absoluteFilePath()));
00216 return 1;
00217 }
00218 DocuParser *parser = DocuParser::createParser( file.absoluteFilePath() );
00219 if( parser ) {
00220 QFile f( QFile::decodeName(argv[i+1]) );
00221 if( !parser->parse( &f ) ) {
00222 fprintf(stderr, "Failed to parse file: %s\n", qPrintable(file.absoluteFilePath()));
00223 return 1;
00224 }
00225 parser->addTo( c->profile() );
00226 c->setDocRebuild( true );
00227 c->save();
00228 }
00229 return 0;
00230 } else if ( opt == QLatin1String("-removecontentfile") ) {
00231 INDEX_CHECK("Missing content file!");
00232 Config *c = Config::loadConfig(QString());
00233 Profile *profile = c->profile();
00234 QString contentFile = QString::fromLocal8Bit(argv[i+i]);
00235 QStringList entries;
00236 #ifdef Q_WS_WIN
00237 contentFile.replace('\\', '/');
00238 entries = profile->docs.filter(contentFile, Qt::CaseInsensitive);
00239 #else
00240 entries = profile->docs.filter(contentFile);
00241 #endif
00242 if (entries.count() == 0) {
00243 fprintf(stderr, "Could not locate content file: %s\n", qPrintable(contentFile));
00244 return 1;
00245 } else if (entries.count() > 1) {
00246 fprintf(stderr, "More than one entry matching file name found, "
00247 "please specify full path to file");
00248 return 1;
00249 } else {
00250 QFileInfo file(entries[0]);
00251 if( !file.exists() ) {
00252 fprintf(stderr, "Could not locate content file: %s\n", qPrintable(file.absoluteFilePath()));
00253 return 1;
00254 }
00255 profile->removeDocFileEntry( file.absoluteFilePath() );
00256 c->setDocRebuild( true );
00257 c->save();
00258 }
00259 return 0;
00260 } else if ( QString( argv[i] ).toLower() == "-docpath" ) {
00261 INDEX_CHECK( "Missing path!" );
00262 QDir dir(QString::fromLocal8Bit(argv[i+1]));
00263 if ( dir.exists() ) {
00264 Config *c = Config::loadConfig(QString());
00265 c->saveProfile(Profile::createDefaultProfile(dir.absolutePath()));
00266 c->loadDefaultProfile();
00267 c->setDocRebuild(true);
00268 c->save();
00269 } else {
00270 fprintf(stderr, "The specified path does not exist!\n");
00271 return 1;
00272 }
00273 } else if ( opt == QLatin1String("-hidesidebar") ) {
00274 hideSidebar = true;
00275 } else if ( opt == QLatin1String("-help") || opt == QLatin1String("/?") ) {
00276 QString helpText = QLatin1String( "Usage: assistant [option]\n"
00277 "Options:\n"
00278 " -file Filename assistant opens the specified file\n"
00279 " -server reads commands from a socket after\n"
00280 " assistant has started\n"
00281 " -profile fileName starts assistant and displays the\n"
00282 " profile specified in the file fileName.\n"
00283 " -addContentFile file adds the content file 'file' to the set of\n"
00284 " documentation available by default\n"
00285 " -removeContentFile file removes the content file 'file' from the\n"
00286 " documentation available by default\n"
00287 " -docPath path sets the Qt documentation root path to\n"
00288 " 'path' and starts assistant\n"
00289 " -hideSidebar assistant will hide the sidebar.\n"
00290 " -resourceDir assistant will load translations from\n"
00291 " this directory.\n"
00292 " -help shows this help.");
00293 #ifdef Q_WS_WIN
00294 QMessageBox::information( 0, QLatin1String("Qt Assistant"),
00295 QLatin1String("<pre>") + helpText + QLatin1String("</pre>") );
00296 #else
00297 fprintf(stdout, "%s\n", qPrintable(helpText));
00298 #endif
00299 exit( 0 );
00300 } else if ( opt == QLatin1String("-resourcedir") ) {
00301 INDEX_CHECK( "Missing resource directory argument!" );
00302 resourceDir = QFile::decodeName( argv[++i] );
00303 } else {
00304 fprintf(stderr, "Unrecognized option %s. Try -help to get help.\n", qPrintable(opt));
00305 }
00306 }
00307 }
00308
00309 if( resourceDir.isNull() )
00310 resourceDir = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
00311
00312 QTranslator translator( 0 );
00313 translator.load( QLatin1String("assistant_") + QLocale::system().name(), resourceDir );
00314 a.installTranslator( &translator );
00315
00316 QTranslator qtTranslator( 0 );
00317 qtTranslator.load( QLatin1String("qt_") + QLocale::system().name(), resourceDir );
00318 a.installTranslator( &qtTranslator );
00319
00320 Config *conf = Config::loadConfig( profileName );
00321 if ( !conf ) {
00322 fprintf( stderr, "Profile '%s' does not exist!\n", profileName.toLatin1().constData() );
00323 fflush( stderr );
00324 return -1;
00325 }
00326
00327 QStringList links = conf->source();
00328 conf->hideSideBar( hideSidebar );
00329
00330 QPointer<MainWindow> mw = new MainWindow();
00331 mw->setObjectName(QLatin1String("Assistant"));
00332
00333 if ( server ) {
00334 as = new AssistantServer();
00335 printf("%d\n", as->serverPort() );
00336 fflush( stdout );
00337 as->connect( as, SIGNAL(showLinkRequest(QString)),
00338 mw, SLOT(showLinkFromClient(QString)) );
00339 }
00340
00341 #if !defined(QT_NO_DBUS) && defined(Q_OS_UNIX)
00342 new AssistantAdaptor(mw);
00343 #endif // QT_NO_DBUS
00344
00345 mw->show();
00346
00347 if ( !file.isEmpty() ) {
00348 mw->showLink( MainWindow::urlifyFileName(file) );
00349 } else if ( file.isEmpty() )
00350 mw->showLinks( links );
00351
00352 a.connect( &a, SIGNAL(lastWindowClosed()), &a, SLOT(quit()) );
00353
00354 int appExec = a.exec();
00355 delete (MainWindow*)mw;
00356 return appExec;
00357 }
00358
00359 #include "main.moc"