UniversalIndentGUI 1.2.0
MainWindow.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2006-2012 by Thomas Schweitzer                          *
00003  *   thomas-schweitzer(at)arcor.de                                         *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License version 2.0 as   *
00007  *   published by the Free Software Foundation.                            *
00008  *                                                                         *
00009  *   This program is distributed in the hope that it will be useful,       *
00010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00012  *   GNU General Public License for more details.                          *
00013  *                                                                         *
00014  *   You should have received a copy of the GNU General Public License     *
00015  *   along with this program in the file LICENSE.GPL; if not, write to the *
00016  *   Free Software Foundation, Inc.,                                       *
00017  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00018  ***************************************************************************/
00019 
00020 #include "MainWindow.h"
00021 #include "ui_MainWindow.h"
00022 
00023 #include "UiGuiVersion.h"
00024 #include "debugging/TSLogger.h"
00025 #include "SettingsPaths.h"
00026 
00027 #include "ui_ToolBarWidget.h"
00028 #include "AboutDialog.h"
00029 #include "AboutDialogGraphicsView.h"
00030 #include "UiGuiSettings.h"
00031 #include "UiGuiSettingsDialog.h"
00032 #include "UiGuiHighlighter.h"
00033 #include "IndentHandler.h"
00034 #include "UpdateCheckDialog.h"
00035 
00036 #include <QWidget>
00037 #include <QLabel>
00038 #include <QString>
00039 #include <QScrollBar>
00040 #include <QTextCursor>
00041 #include <QFileDialog>
00042 #include <QTextStream>
00043 #include <QTextDocument>
00044 #include <QPrinter>
00045 #include <QPrintDialog>
00046 #include <QCloseEvent>
00047 #include <QHelpEvent>
00048 #include <QToolTip>
00049 #include <QTranslator>
00050 #include <QLocale>
00051 #include <QTextCodec>
00052 #include <QDate>
00053 #include <QUrl>
00054 #include <QMessageBox>
00055 #include <QtDebug>
00056 
00057 #include <Qsci/qsciscintilla.h>
00058 #include <Qsci/qsciprinter.h>
00059 
00060 using namespace tschweitzer;
00061 
00063 
00077 MainWindow::MainWindow(QString file2OpenOnStart, QWidget *parent) : QMainWindow(parent)
00078     , _mainWindowForm(NULL)
00079     , _qSciSourceCodeEditor(NULL)
00080     , _settings(NULL)
00081     , _highlighter(NULL)
00082     , _textEditVScrollBar(NULL)
00083     , _aboutDialog(NULL)
00084     , _aboutDialogGraphicsView(NULL)
00085     , _settingsDialog(NULL)
00086     , _encodingActionGroup(NULL)
00087     , _saveEncodedActionGroup(NULL)
00088     , _highlighterActionGroup(NULL)
00089     , _uiGuiTranslator(NULL)
00090     , _qTTranslator(NULL)
00091     , _toolBarWidget(NULL)
00092     , _indentHandler(NULL)
00093     , _updateCheckDialog(NULL)
00094     , _textEditLineColumnInfoLabel(NULL)
00095 {
00096     // Init of some variables.
00097     _sourceCodeChanged = false;
00098     _scrollPositionChanged = false;
00099 
00100     // Create the _settings object, which loads all UiGui settings from a file.
00101     _settings = UiGuiSettings::getInstance();
00102 
00103     // Initialize the language of the application.
00104     initApplicationLanguage();
00105 
00106     // Creates the main window and initializes it.
00107     initMainWindow();
00108 
00109     // Create toolbar and insert it into the main window.
00110     initToolBar();
00111 
00112     // Create the text edit component using the QScintilla widget.
00113     initTextEditor();
00114 
00115     // Create and init the syntax highlighter.
00116     initSyntaxHighlighter();
00117 
00118     // Create and init the indenter.
00119     initIndenter();
00120 
00121     // Create some menus.
00122     createEncodingMenu();
00123     createHighlighterMenu();
00124 
00125 
00126     // Generate about dialog box
00127     _aboutDialog = new AboutDialog(this, Qt::SplashScreen);
00128     _aboutDialogGraphicsView = new AboutDialogGraphicsView(_aboutDialog, this);
00129     connect( _toolBarWidget->pbAbout, SIGNAL(clicked()), this, SLOT(showAboutDialog()) );
00130     connect( _mainWindowForm->actionAbout_UniversalIndentGUI, SIGNAL(triggered()), this, SLOT(showAboutDialog()) );
00131 
00132     // Generate settings dialog box
00133     _settingsDialog = new UiGuiSettingsDialog(this, _settings);
00134     connect( _mainWindowForm->actionShowSettings, SIGNAL(triggered()), _settingsDialog, SLOT(showDialog()) );
00135 
00136     // If a file that should be opened on start has been handed over to the constructor exists, load it
00137     if ( QFile::exists(file2OpenOnStart) ) {
00138         openSourceFileDialog(file2OpenOnStart);
00139     }
00140     // Otherwise load the last opened file, if this is enabled in the settings.
00141     else {
00142         loadLastOpenedFile();
00143     }
00144 
00145     updateSourceView();
00146 
00147     // Check if a newer version is available but only if the setting for that is enabled and today not already a check has been done.
00148     if ( _settings->getValueByName("CheckForUpdate").toBool() && QDate::currentDate() != _settings->getValueByName("LastUpdateCheck").toDate() ) {
00149         _updateCheckDialog->checkForUpdate();
00150     }
00151 
00152     // Enable accept dropping of files.
00153     setAcceptDrops(true);
00154 }
00155 
00156 
00160 void MainWindow::initMainWindow() {
00161     // Generate gui as it is build in the file "mainwindow.ui"
00162     _mainWindowForm = new Ui::MainWindowUi();
00163     _mainWindowForm->setupUi(this);
00164 
00165     // Handle last opened window size
00166     // ------------------------------
00167     bool maximized = _settings->getValueByName("maximized").toBool();
00168     QPoint pos = _settings->getValueByName("position").toPoint();
00169     QSize size = _settings->getValueByName("size").toSize();
00170     resize(size);
00171     move(pos);
00172     if ( maximized ) {
00173         showMaximized();
00174     }
00175 #ifndef Q_OS_MAC // On Mac restoring the window state causes the screenshot no longer to work.
00176     restoreState( _settings->getValueByName("MainWindowState").toByteArray() );
00177 #endif
00178 
00179     // Handle if first run of this version
00180     // -----------------------------------
00181     QString readVersion = _settings->getValueByName("version").toString();
00182     // If version strings are not equal set first run true.
00183     if ( readVersion != PROGRAM_VERSION_STRING ) {
00184         _isFirstRunOfThisVersion = true;
00185     }
00186     else {
00187         _isFirstRunOfThisVersion = false;
00188     }
00189 
00190     // Get last selected file encoding
00191     // -------------------------------
00192     _currentEncoding = _settings->getValueByName("encoding").toString();
00193 
00194     _updateCheckDialog = new UpdateCheckDialog(_settings, this);
00195 
00196     // Register the load last file setting in the menu to the _settings object.
00197     _settings->registerObjectProperty(_mainWindowForm->loadLastOpenedFileOnStartupAction, "checked", "loadLastSourceCodeFileOnStartup");
00198 
00199     // Tell the QScintilla editor if it has to show white space.
00200     connect( _mainWindowForm->whiteSpaceIsVisibleAction, SIGNAL(toggled(bool)), this, SLOT(setWhiteSpaceVisibility(bool)) );
00201     // Register the white space setting in the menu to the _settings object.
00202     _settings->registerObjectProperty(_mainWindowForm->whiteSpaceIsVisibleAction, "checked", "whiteSpaceIsVisible");
00203 
00204     // Connect the remaining menu items.
00205     connect( _mainWindowForm->actionOpen_Source_File, SIGNAL(triggered()), this, SLOT(openSourceFileDialog()) );
00206     connect( _mainWindowForm->actionSave_Source_File_As, SIGNAL(triggered()), this, SLOT(saveasSourceFileDialog()) );
00207     connect( _mainWindowForm->actionSave_Source_File, SIGNAL(triggered()), this, SLOT(saveSourceFile()) );
00208     connect( _mainWindowForm->actionExportPDF, SIGNAL(triggered()), this, SLOT(exportToPDF()) );
00209     connect( _mainWindowForm->actionExportHTML, SIGNAL(triggered()), this, SLOT(exportToHTML()) );
00210     connect( _mainWindowForm->actionCheck_for_update, SIGNAL(triggered()), _updateCheckDialog, SLOT(checkForUpdateAndShowDialog()) );
00211     connect( _mainWindowForm->actionShowLog, SIGNAL(triggered()), debugging::TSLogger::getInstance(), SLOT(show()) );
00212 
00213     // Init the menu for selecting one of the recently opened files.
00214     updateRecentlyOpenedList();
00215     connect( _mainWindowForm->menuRecently_Opened_Files, SIGNAL(triggered(QAction*)), this, SLOT(openFileFromRecentlyOpenedList(QAction*)) );
00216     //connect( _settings, SIGNAL(recentlyOpenedListSize(int)), this, SLOT(updateRecentlyOpenedList()) );
00217     _settings->registerObjectSlot(this, "updateRecentlyOpenedList()", "recentlyOpenedListSize");
00218 }
00219 
00220 
00224 void MainWindow::initToolBar() {
00225     // Create the tool bar and add it to the main window.
00226     _toolBarWidget = new Ui::ToolBarWidget();
00227     QWidget* helpWidget = new QWidget();
00228     _toolBarWidget->setupUi(helpWidget);
00229     _mainWindowForm->toolBar->addWidget(helpWidget);
00230     _mainWindowForm->toolBar->setAllowedAreas( Qt::TopToolBarArea | Qt::BottomToolBarArea );
00231 
00232     // Connect the tool bar widgets to their functions.
00233     _settings->registerObjectProperty(_toolBarWidget->enableSyntaxHighlightningCheckBox, "checked", "SyntaxHighlightingEnabled");
00234     _toolBarWidget->enableSyntaxHighlightningCheckBox->hide();
00235     connect( _toolBarWidget->pbOpen_Source_File, SIGNAL(clicked()), this, SLOT(openSourceFileDialog()) );
00236     connect( _toolBarWidget->pbExit, SIGNAL(clicked()), this, SLOT(close()));
00237     connect( _toolBarWidget->cbLivePreview, SIGNAL(toggled(bool)), this, SLOT(previewTurnedOnOff(bool)) );
00238     connect( _toolBarWidget->cbLivePreview, SIGNAL(toggled(bool)), _mainWindowForm->actionLive_Indent_Preview, SLOT(setChecked(bool)) );
00239     connect( _mainWindowForm->actionLive_Indent_Preview, SIGNAL(toggled(bool)), _toolBarWidget->cbLivePreview, SLOT(setChecked(bool)) );
00240 }
00241 
00242 
00246 void MainWindow::initTextEditor() {
00247     // Create the QScintilla widget and add it to the layout.
00248     qDebug() << "Trying to load QScintilla library. If anything fails during loading, it might be possible that"
00249         << " the debug and release version of QScintilla are mixed or the library cannot be found at all.";
00250     // Try and catch doesn't seem to catch the runtime error when starting UiGUI release with QScintilla debug lib and the other way around.
00251     try {
00252         _qSciSourceCodeEditor = new QsciScintilla(this);
00253     }
00254     catch (...) {
00255         QMessageBox::critical(this, "Error creating QScintilla text editor component!",
00256             "During trying to create the text editor component, that is based on QScintilla, an error occurred. Please make sure that you have installed QScintilla and not mixed release and debug versions." );
00257         exit(1);
00258     }
00259     _mainWindowForm->hboxLayout1->addWidget(_qSciSourceCodeEditor);
00260 
00261     // Make some _settings for the QScintilla widget.
00262     _qSciSourceCodeEditor->setUtf8(true);
00263     _qSciSourceCodeEditor->setMarginLineNumbers(1, true);
00264     _qSciSourceCodeEditor->setMarginWidth(1, QString("10000") );
00265     _qSciSourceCodeEditor->setBraceMatching(_qSciSourceCodeEditor->SloppyBraceMatch);
00266     _qSciSourceCodeEditor->setMatchedBraceForegroundColor( QColor("red") );
00267     _qSciSourceCodeEditor->setFolding(QsciScintilla::BoxedTreeFoldStyle);
00268     _qSciSourceCodeEditor->setAutoCompletionSource(QsciScintilla::AcsAll);
00269     _qSciSourceCodeEditor->setAutoCompletionThreshold(3);
00270 
00271     // Handle if white space is set to be visible
00272     bool whiteSpaceIsVisible = _settings->getValueByName("whiteSpaceIsVisible").toBool();
00273     setWhiteSpaceVisibility( whiteSpaceIsVisible );
00274 
00275     // Handle the width of tabs in spaces
00276     int tabWidth = _settings->getValueByName("tabWidth").toInt();
00277     _qSciSourceCodeEditor->setTabWidth(tabWidth);
00278 
00279     // Remember a pointer to the scrollbar of the QScintilla widget used to keep
00280     // on the same line as before when turning preview on/off.
00281     _textEditVScrollBar = _qSciSourceCodeEditor->verticalScrollBar();
00282 
00283     // Add a column row indicator to the status bar.
00284     _textEditLineColumnInfoLabel = new QLabel( tr("Line %1, Column %2").arg(1).arg(1) );
00285     _mainWindowForm->statusbar->addPermanentWidget(_textEditLineColumnInfoLabel);
00286     connect( _qSciSourceCodeEditor, SIGNAL(cursorPositionChanged(int, int)), this, SLOT(setStatusBarCursorPosInfo(int, int)) );
00287 
00288     // Connect the text editor to dependent functions.
00289     connect( _qSciSourceCodeEditor, SIGNAL(textChanged()), this, SLOT(sourceCodeChangedHelperSlot()) );
00290     connect( _qSciSourceCodeEditor, SIGNAL(linesChanged()), this, SLOT(numberOfLinesChanged()) );
00291     //connect( _settings, SIGNAL(tabWidth(int)), _qSciSourceCodeEditor, SLOT(setTabWidth(int)) );
00292     _settings->registerObjectSlot(_qSciSourceCodeEditor, "setTabWidth(int)", "tabWidth");
00293     _qSciSourceCodeEditor->setTabWidth( _settings->getValueByName("tabWidth").toInt() );
00294 }
00295 
00296 
00300 void MainWindow::initSyntaxHighlighter() {
00301     // Create the _highlighter.
00302     _highlighter = new UiGuiHighlighter(_qSciSourceCodeEditor);
00303 
00304     // Connect the syntax highlighting setting in the menu to the turnHighlightOnOff function.
00305     connect( _mainWindowForm->enableSyntaxHighlightingAction, SIGNAL(toggled(bool)), this, SLOT(turnHighlightOnOff(bool)) );
00306 
00307     // Register the syntax highlighting setting in the menu to the _settings object.
00308     _settings->registerObjectProperty(_mainWindowForm->enableSyntaxHighlightingAction, "checked", "SyntaxHighlightingEnabled");
00309 }
00310 
00311 
00321 bool MainWindow::initApplicationLanguage() {
00322     QString languageShort;
00323 
00324     // Get the language _settings from the _settings object.
00325     int languageIndex = _settings->getValueByName("language").toInt();
00326 
00327     // If no language was set, indicated by a negative index, use the system language.
00328     if ( languageIndex < 0 ) {
00329         languageShort = QLocale::system().name();
00330 
00331         // Chinese and Japanese language consist of country and language code.
00332         // For all others the language code will be cut off.
00333         if ( languageShort.left(2) != "zh" && languageShort.left(2) != "ja" ) {
00334             languageShort = languageShort.left(2);
00335         }
00336 
00337         // If no translation file for the systems local language exist, fall back to English.
00338         if ( _settings->getAvailableTranslations().indexOf(languageShort) < 0 ) {
00339             languageShort = "en";
00340         }
00341 
00342         // Set the language setting to the new language.
00343         _settings->setValueByName("language", _settings->getAvailableTranslations().indexOf(languageShort) );
00344     }
00345     // If a language was defined in the _settings, get this language mnemonic.
00346     else {
00347         languageShort = _settings->getAvailableTranslations().at(languageIndex);
00348     }
00349 
00350     // Load the Qt own translation file and set it for the application.
00351     _qTTranslator = new QTranslator();
00352     bool translationFileLoaded;
00353     translationFileLoaded = _qTTranslator->load( SettingsPaths::getGlobalFilesPath() + "/translations/qt_" + languageShort );
00354     if ( translationFileLoaded ) {
00355         qApp->installTranslator(_qTTranslator);
00356     }
00357 
00358     // Load the uigui translation file and set it for the application.
00359     _uiGuiTranslator = new QTranslator();
00360     translationFileLoaded = _uiGuiTranslator->load( SettingsPaths::getGlobalFilesPath() + "/translations/universalindent_" + languageShort );
00361     if ( translationFileLoaded ) {
00362         qApp->installTranslator(_uiGuiTranslator);
00363     }
00364 
00365     //connect( _settings, SIGNAL(language(int)), this, SLOT(languageChanged(int)) );
00366     _settings->registerObjectSlot(this, "languageChanged(int)", "language");
00367 
00368     return translationFileLoaded;
00369 }
00370 
00371 
00375 void MainWindow::initIndenter() {
00376     // Get Id of last selected indenter.
00377     _currentIndenterID = _settings->getValueByName("selectedIndenter").toInt();
00378 
00379     // Create the indenter widget with the ID and add it to the layout.
00380     _indentHandler = new IndentHandler(_currentIndenterID, this, _mainWindowForm->centralwidget);
00381     _mainWindowForm->vboxLayout->addWidget(_indentHandler);
00382 
00383     // If _settings for the indenter have changed, let the main window know aboud it.
00384     connect(_indentHandler, SIGNAL(indenterSettingsChanged()), this, SLOT(indentSettingsChangedSlot()));
00385 
00386     // Set this true, so the indenter is called at first program start
00387     _indentSettingsChanged = true;
00388     _previewToggled = true;
00389 
00390     // Handle if indenter parameter tool tips are enabled
00391     _settings->registerObjectProperty(_mainWindowForm->indenterParameterTooltipsEnabledAction, "checked", "indenterParameterTooltipsEnabled");
00392 
00393     // Add the indenters context menu to the mainwindows menu.
00394     _mainWindowForm->menuIndenter->addActions( _indentHandler->getIndenterMenuActions() );
00395 }
00396 
00397 
00403 QString MainWindow::loadFile(QString filePath) {
00404     QFile inSrcFile(filePath);
00405     QString fileContent = "";
00406 
00407     if ( !inSrcFile.open(QFile::ReadOnly | QFile::Text) ) {
00408         QMessageBox::warning(NULL, tr("Error opening file"), tr("Cannot read the file ")+"\""+filePath+"\"." );
00409     }
00410     else {
00411         QTextStream inSrcStrm(&inSrcFile);
00412         QApplication::setOverrideCursor(Qt::WaitCursor);
00413         inSrcStrm.setCodec( QTextCodec::codecForName(_currentEncoding.toAscii()) );
00414         fileContent = inSrcStrm.readAll();
00415         QApplication::restoreOverrideCursor();
00416         inSrcFile.close();
00417 
00418         QFileInfo fileInfo(filePath);
00419         _currentSourceFileExtension = fileInfo.suffix();
00420         int indexOfHighlighter = _highlighter->setLexerForExtension( _currentSourceFileExtension );
00421         _highlighterActionGroup->actions().at(indexOfHighlighter)->setChecked(true);
00422     }
00423     return fileContent;
00424 }
00425 
00426 
00432 void MainWindow::openSourceFileDialog(QString fileName) {
00433     // If the source code file is changed and the shown dialog for saving the file
00434     // is canceled, also stop opening another source file.
00435     if ( !maybeSave() ) {
00436         return;
00437     }
00438     QString openedSourceFileContent = "";
00439     QString fileExtensions = tr("Supported by indenter")+" ("+_indentHandler->getPossibleIndenterFileExtensions()+
00440         ");;"+tr("All files")+" (*.*)";
00441 
00442     //QString openedSourceFileContent = openFileDialog( tr("Choose source code file"), "./", fileExtensions );
00443     if ( fileName.isEmpty() ) {
00444         fileName = QFileDialog::getOpenFileName( this, tr("Choose source code file"), _currentSourceFile, fileExtensions);
00445     }
00446 
00447     if (fileName != "") {
00448         _currentSourceFile = fileName;
00449         QFileInfo fileInfo(fileName);
00450         _currentSourceFileExtension = fileInfo.suffix();
00451 
00452         openedSourceFileContent = loadFile(fileName);
00453         _sourceFileContent = openedSourceFileContent;
00454         if ( _toolBarWidget->cbLivePreview->isChecked() ) {
00455             callIndenter();
00456         }
00457         _sourceCodeChanged = true;
00458         _previewToggled = true;
00459         updateSourceView();
00460         updateWindowTitle();
00461         updateRecentlyOpenedList();
00462         _textEditLastScrollPos = 0;
00463         _textEditVScrollBar->setValue( _textEditLastScrollPos );
00464 
00465         _savedSourceContent = openedSourceFileContent;
00466         _qSciSourceCodeEditor->setModified( false );
00467         setWindowModified( false );
00468     }
00469 }
00470 
00471 
00477 bool MainWindow::saveasSourceFileDialog(QAction *chosenEncodingAction) {
00478     QString encoding;
00479     QString fileExtensions = tr("Supported by indenter")+" ("+_indentHandler->getPossibleIndenterFileExtensions()+
00480         ");;"+tr("All files")+" (*.*)";
00481 
00482     //QString openedSourceFileContent = openFileDialog( tr("Choose source code file"), "./", fileExtensions );
00483     QString fileName = QFileDialog::getSaveFileName( this, tr("Save source code file"), _currentSourceFile, fileExtensions);
00484 
00485     // Saving has been canceled if the filename is empty
00486     if ( fileName.isEmpty() ) {
00487         return false;
00488     }
00489 
00490     _savedSourceContent = _qSciSourceCodeEditor->text();
00491 
00492     _currentSourceFile = fileName;
00493     QFile::remove(fileName);
00494     QFile outSrcFile(fileName);
00495     outSrcFile.open( QFile::ReadWrite | QFile::Text );
00496 
00497     // Get current encoding.
00498     if ( chosenEncodingAction != NULL ) {
00499         encoding = chosenEncodingAction->text();
00500     }
00501     else {
00502         encoding = _encodingActionGroup->checkedAction()->text();
00503     }
00504     QTextStream outSrcStrm(&outSrcFile);
00505     outSrcStrm.setCodec( QTextCodec::codecForName(encoding.toAscii()) );
00506     outSrcStrm << _savedSourceContent;
00507     outSrcFile.close();
00508 
00509     QFileInfo fileInfo(fileName);
00510     _currentSourceFileExtension = fileInfo.suffix();
00511 
00512     _qSciSourceCodeEditor->setModified( false );
00513     setWindowModified( false );
00514 
00515     updateWindowTitle();
00516     return true;
00517 }
00518 
00519 
00526 bool MainWindow::saveSourceFile() {
00527     if ( _currentSourceFile.isEmpty() ) {
00528         return saveasSourceFileDialog();
00529     }
00530     else {
00531         QFile::remove(_currentSourceFile);
00532         QFile outSrcFile(_currentSourceFile);
00533         _savedSourceContent = _qSciSourceCodeEditor->text();
00534         outSrcFile.open( QFile::ReadWrite | QFile::Text );
00535 
00536         // Get current encoding.
00537         QString _currentEncoding = _encodingActionGroup->checkedAction()->text();
00538         QTextStream outSrcStrm(&outSrcFile);
00539         outSrcStrm.setCodec( QTextCodec::codecForName(_currentEncoding.toAscii()) );
00540         outSrcStrm << _savedSourceContent;
00541         outSrcFile.close();
00542 
00543         _qSciSourceCodeEditor->setModified( false );
00544         setWindowModified( false );
00545     }
00546     return true;
00547 }
00548 
00549 
00556 QString MainWindow::openFileDialog(QString dialogHeaderStr, QString startPath, QString fileMaskStr) {
00557     QString fileContent = "";
00558 
00559     QString fileName = QFileDialog::getOpenFileName( NULL, dialogHeaderStr, startPath, fileMaskStr);
00560 
00561     if (fileName != "") {
00562         fileContent = loadFile(fileName);
00563     }
00564 
00565     return fileContent;
00566 }
00567 
00568 
00576 void MainWindow::updateSourceView() {
00577     _textEditLastScrollPos = _textEditVScrollBar->value();
00578 
00579     if ( _toolBarWidget->cbLivePreview->isChecked() ) {
00580         _sourceViewContent = _sourceFormattedContent;
00581     }
00582     else {
00583         _sourceViewContent = _sourceFileContent;
00584     }
00585 
00586     if (_previewToggled) {
00587         disconnect( _qSciSourceCodeEditor, SIGNAL(textChanged ()), this, SLOT(sourceCodeChangedHelperSlot()) );
00588         bool textIsModified = isWindowModified();
00589         _qSciSourceCodeEditor->setText(_sourceViewContent);
00590         setWindowModified(textIsModified);
00591         _previewToggled = false;
00592         connect( _qSciSourceCodeEditor, SIGNAL(textChanged ()), this, SLOT(sourceCodeChangedHelperSlot()) );
00593     }
00594 
00595     _textEditVScrollBar->setValue( _textEditLastScrollPos );
00596 }
00597 
00598 
00604 void MainWindow::callIndenter() {
00605     QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
00606     _sourceFormattedContent = _indentHandler->callIndenter(_sourceFileContent, _currentSourceFileExtension);
00607     //updateSourceView();
00608     QApplication::restoreOverrideCursor();
00609 }
00610 
00611 
00615 void MainWindow::turnHighlightOnOff(bool turnOn) {
00616     if ( turnOn ) {
00617         _highlighter->turnHighlightOn();
00618     }
00619     else {
00620         _highlighter->turnHighlightOff();
00621     }
00622     _previewToggled = true;
00623     updateSourceView();
00624 }
00625 
00626 
00630 void MainWindow::sourceCodeChangedHelperSlot() {
00631     QTimer::singleShot(0, this, SLOT(sourceCodeChangedSlot()));
00632 }
00633 
00634 
00639 void MainWindow::sourceCodeChangedSlot() {
00640     QChar enteredCharacter;
00641     int cursorPos, cursorPosAbsolut, cursorLine;
00642     QString text;
00643 
00644     _sourceCodeChanged = true;
00645     if ( _scrollPositionChanged ) {
00646         _scrollPositionChanged = false;
00647     }
00648 
00649     // Get the content text of the text editor.
00650     _sourceFileContent = _qSciSourceCodeEditor->text();
00651 
00652     // Get the position of the cursor in the unindented text.
00653     if ( _sourceFileContent.isEmpty() ) {
00654         // Add this line feed, because AStyle has problems with a totally emtpy file.
00655         _sourceFileContent += "\n";
00656         cursorPosAbsolut = 0;
00657         cursorPos = 0;
00658         cursorLine = 0;
00659         enteredCharacter = _sourceFileContent.at(cursorPosAbsolut);
00660     }
00661     else {
00662         _qSciSourceCodeEditor->getCursorPosition(&cursorLine, &cursorPos);
00663         cursorPosAbsolut = _qSciSourceCodeEditor->SendScintilla(QsciScintillaBase::SCI_GETCURRENTPOS);
00664         text = _qSciSourceCodeEditor->text(cursorLine);
00665         if ( cursorPosAbsolut > 0 ) {
00666             cursorPosAbsolut--;
00667         }
00668         if ( cursorPos > 0 ) {
00669             cursorPos--;
00670         }
00671         enteredCharacter = _sourceFileContent.at(cursorPosAbsolut);
00672     }
00673 
00674     // Call the indenter to reformat the text.
00675     if ( _toolBarWidget->cbLivePreview->isChecked() ) {
00676         callIndenter();
00677         _previewToggled = true;
00678     }
00679 
00680     // Update the text editor.
00681     updateSourceView();
00682 
00683     if ( _toolBarWidget->cbLivePreview->isChecked() && !enteredCharacter.isNull() && enteredCharacter != 10 ) {
00684         //const char ch = enteredCharacter.toAscii();
00685 
00686         int saveCursorLine = cursorLine;
00687         int saveCursorPos = cursorPos;
00688 
00689         bool charFound = false;
00690 
00691         // Search forward
00692         for ( cursorLine = saveCursorLine; cursorLine-saveCursorLine < 6 && cursorLine < _qSciSourceCodeEditor->lines(); cursorLine++ ) {
00693             text = _qSciSourceCodeEditor->text(cursorLine);
00694             while ( cursorPos < text.count() && enteredCharacter != text.at(cursorPos)) {
00695                 cursorPos++;
00696             }
00697             if ( cursorPos >= text.count() ) {
00698                 cursorPos = 0;
00699             }
00700             else {
00701                 charFound = true;
00702                 break;
00703             }
00704         }
00705 
00706         // If foward search did not find the character, search backward
00707         if ( !charFound ) {
00708             text = _qSciSourceCodeEditor->text(saveCursorLine);
00709             cursorPos = saveCursorPos;
00710             if ( cursorPos >= text.count() ) {
00711                 cursorPos = text.count() - 1;
00712             }
00713 
00714             for ( cursorLine = saveCursorLine; saveCursorLine-cursorLine < 6 && cursorLine >= 0; cursorLine-- ) {
00715                 text = _qSciSourceCodeEditor->text(cursorLine);
00716                 while ( cursorPos >= 0 && enteredCharacter != text.at(cursorPos)) {
00717                     cursorPos--;
00718                 }
00719                 if ( cursorPos < 0 ) {
00720                     cursorPos = _qSciSourceCodeEditor->lineLength(cursorLine-1) - 1;
00721                 }
00722                 else {
00723                     charFound = true;
00724                     break;
00725                 }
00726             }
00727         }
00728 
00729         // If the character was found set its new cursor position...
00730         if ( charFound ) {
00731             _qSciSourceCodeEditor->setCursorPosition( cursorLine, cursorPos+1 );
00732         }
00733         // ...if it was not found, set the previous cursor position.
00734         else {
00735             _qSciSourceCodeEditor->setCursorPosition( saveCursorLine, saveCursorPos+1 );
00736         }
00737     }
00738     // set the previous cursor position.
00739     else if ( enteredCharacter == 10 ) {
00740         _qSciSourceCodeEditor->setCursorPosition( cursorLine, cursorPos );
00741     }
00742 
00743 
00744     if ( _toolBarWidget->cbLivePreview->isChecked() ) {
00745         _sourceCodeChanged = false;
00746     }
00747 
00748     if ( _savedSourceContent == _qSciSourceCodeEditor->text() ) {
00749         _qSciSourceCodeEditor->setModified( false );
00750         setWindowModified( false );
00751     }
00752     else {
00753         _qSciSourceCodeEditor->setModified( true ); // Has no effect according to QScintilla docs.
00754         setWindowModified( true );
00755     }
00756 
00757     // Could set cursor this way and use normal linear search in text instead of columns and rows.
00758     //_qSciSourceCodeEditor->SendScintilla(QsciScintillaBase::SCI_SETCURRENTPOS, 50);
00759     //_qSciSourceCodeEditor->SendScintilla(QsciScintillaBase::SCI_SETANCHOR, 50);
00760 }
00761 
00762 
00769 void MainWindow::indentSettingsChangedSlot() {
00770     _indentSettingsChanged = true;
00771 
00772     int cursorLine, cursorPos;
00773     _qSciSourceCodeEditor->getCursorPosition(&cursorLine, &cursorPos);
00774 
00775     if ( _toolBarWidget->cbLivePreview->isChecked() ) {
00776         callIndenter();
00777         _previewToggled = true;
00778 
00779         updateSourceView();
00780         if (_sourceCodeChanged) {
00781 /*            savedCursor = _qSciSourceCodeEditor->textCursor();
00782             if ( cursorPos >= _qSciSourceCodeEditor->text().count() ) {
00783                 cursorPos = _qSciSourceCodeEditor->text().count() - 1;
00784             }
00785             savedCursor.setPosition( cursorPos );
00786             _qSciSourceCodeEditor->setTextCursor( savedCursor );
00787 */
00788             _sourceCodeChanged = false;
00789         }
00790         _indentSettingsChanged = false;
00791     }
00792     else {
00793         updateSourceView();
00794     }
00795 
00796     if ( _savedSourceContent == _qSciSourceCodeEditor->text() ) {
00797         _qSciSourceCodeEditor->setModified( false );
00798         setWindowModified( false );
00799     }
00800     else {
00801         _qSciSourceCodeEditor->setModified( true ); // Has no effect according to QScintilla docs.
00802         setWindowModified( true );
00803     }
00804 }
00805 
00806 
00813 void MainWindow::previewTurnedOnOff(bool turnOn) {
00814     _previewToggled = true;
00815 
00816     int cursorLine, cursorPos;
00817     _qSciSourceCodeEditor->getCursorPosition(&cursorLine, &cursorPos);
00818 
00819     if ( turnOn && (_indentSettingsChanged || _sourceCodeChanged) ) {
00820         callIndenter();
00821     }
00822     updateSourceView();
00823     if (_sourceCodeChanged) {
00824 /*        savedCursor = _qSciSourceCodeEditor->textCursor();
00825         if ( cursorPos >= _qSciSourceCodeEditor->text().count() ) {
00826             cursorPos = _qSciSourceCodeEditor->text().count() - 1;
00827         }
00828         savedCursor.setPosition( cursorPos );
00829         _qSciSourceCodeEditor->setTextCursor( savedCursor );
00830 */
00831         _sourceCodeChanged = false;
00832     }
00833     _indentSettingsChanged = false;
00834 
00835     if ( _savedSourceContent == _qSciSourceCodeEditor->text() ) {
00836         _qSciSourceCodeEditor->setModified( false );
00837         setWindowModified( false );
00838     }
00839     else {
00840         _qSciSourceCodeEditor->setModified( true );
00841         setWindowModified( true );
00842     }
00843 }
00844 
00845 
00850 void MainWindow::updateWindowTitle() {
00851     this->setWindowTitle( "UniversalIndentGUI " + QString(PROGRAM_VERSION_STRING) + " [*]" + _currentSourceFile );
00852 }
00853 
00854 
00858 void MainWindow::exportToPDF() {
00859     QString fileExtensions = tr("PDF Document")+" (*.pdf)";
00860 
00861     QString fileName = _currentSourceFile;
00862     QFileInfo fileInfo(fileName);
00863     QString fileExtension = fileInfo.suffix();
00864 
00865     fileName.replace( fileName.length()-fileExtension.length(), fileExtension.length(), "pdf" );
00866     fileName = QFileDialog::getSaveFileName( this, tr("Export source code file"), fileName, fileExtensions);
00867 
00868     if ( !fileName.isEmpty() ) {
00869         QsciPrinter printer(QPrinter::HighResolution);
00870         printer.setOutputFormat(QPrinter::PdfFormat);
00871         printer.setOutputFileName(fileName);
00872         printer.printRange(_qSciSourceCodeEditor);
00873     }
00874 }
00875 
00876 
00880 void MainWindow::exportToHTML() {
00881     QString fileExtensions = tr("HTML Document")+" (*.html)";
00882 
00883     QString fileName = _currentSourceFile;
00884     QFileInfo fileInfo(fileName);
00885     QString fileExtension = fileInfo.suffix();
00886 
00887     fileName.replace( fileName.length()-fileExtension.length(), fileExtension.length(), "html" );
00888     fileName = QFileDialog::getSaveFileName( this, tr("Export source code file"), fileName, fileExtensions);
00889 
00890     if ( !fileName.isEmpty() ) {
00891         // Create a document from which HTML code can be generated.
00892         QTextDocument sourceCodeDocument( _qSciSourceCodeEditor->text() );
00893         sourceCodeDocument.setDefaultFont( QFont("Courier", 12, QFont::Normal) );
00894         QString sourceCodeAsHTML = sourceCodeDocument.toHtml();
00895         // To ensure that empty lines are kept in the HTML code make this replacement.
00896         sourceCodeAsHTML.replace("\"></p>", "\"><br /></p>");
00897 
00898         // Write the HTML file.
00899         QFile::remove(fileName);
00900         QFile outSrcFile(fileName);
00901         outSrcFile.open( QFile::ReadWrite | QFile::Text );
00902         outSrcFile.write( sourceCodeAsHTML.toAscii() );
00903         outSrcFile.close();
00904     }
00905 }
00906 
00907 
00915 void MainWindow::loadLastOpenedFile() {
00916     // Get setting for last opened source code file.
00917     _loadLastSourceCodeFileOnStartup = _settings->getValueByName("loadLastSourceCodeFileOnStartup").toBool();
00918 
00919     // Only load last source code file if set to do so
00920     if ( _loadLastSourceCodeFileOnStartup ) {
00921         // From the list of last opened files get the first one.
00922         _currentSourceFile = _settings->getValueByName("lastSourceCodeFile").toString().split("|").first();
00923 
00924         // If source file exist load it.
00925         if ( QFile::exists(_currentSourceFile) ) {
00926             QFileInfo fileInfo(_currentSourceFile);
00927             _currentSourceFile = fileInfo.absoluteFilePath();
00928             _sourceFileContent = loadFile(_currentSourceFile);
00929         }
00930         // If the last opened source code file does not exist, try to load the default example.cpp file.
00931         else if ( QFile::exists( SettingsPaths::getIndenterPath() + "/example.cpp" ) ) {
00932             QFileInfo fileInfo( SettingsPaths::getIndenterPath() + "/example.cpp" );
00933             _currentSourceFile = fileInfo.absoluteFilePath();
00934             _sourceFileContent = loadFile(_currentSourceFile);
00935         }
00936         // If neither the example source code file exists show some small code example.
00937         else {
00938             _currentSourceFile = "untitled.cpp";
00939             _currentSourceFileExtension = "cpp";
00940             _sourceFileContent = "if(x==\"y\"){x=z;}";
00941         }
00942     }
00943     // if last opened source file should not be loaded make some default _settings.
00944     else {
00945         _currentSourceFile = "untitled.cpp";
00946         _currentSourceFileExtension = "cpp";
00947         _sourceFileContent = "";
00948     }
00949     _savedSourceContent = _sourceFileContent;
00950 
00951     // Update the mainwindow title to show the name of the loaded source code file.
00952     updateWindowTitle();
00953 }
00954 
00955 
00961 void MainWindow::saveSettings() {
00962     _settings->setValueByName( "encoding", _currentEncoding );
00963     _settings->setValueByName( "version", PROGRAM_VERSION_STRING );
00964     _settings->setValueByName( "maximized", isMaximized() );
00965     if ( !isMaximized() ) {
00966         _settings->setValueByName( "position", pos() );
00967         _settings->setValueByName( "size", size() );
00968     }
00969     _settings->setValueByName( "MainWindowState", saveState() );
00970 
00971     // Also save the syntax highlight style for all lexers.
00972     _highlighter->writeCurrentSettings("");
00973 }
00974 
00975 
00979 void MainWindow::closeEvent( QCloseEvent *event ) {
00980     if ( maybeSave() ) {
00981         saveSettings();
00982         event->accept();
00983     }
00984     else {
00985         event->ignore();
00986     }
00987 }
00988 
00989 
00997 bool MainWindow::eventFilter(QObject *obj, QEvent *event) {
00998     if ( event->type() == QEvent::ToolTip) {
00999         if ( _mainWindowForm->indenterParameterTooltipsEnabledAction->isChecked() ) {
01000             return QMainWindow::eventFilter(obj, event);
01001         }
01002         else {
01003             //QToolTip::showText( QPoint(100,100) , "Test1");
01004             return true;
01005         }
01006     }
01007     else {
01008         // pass the event on to the parent class
01009         return QMainWindow::eventFilter(obj, event);
01010     }
01011 }
01012 
01013 
01017 bool MainWindow::maybeSave() {
01018     if ( isWindowModified() ) {
01019         int ret = QMessageBox::warning(this, tr("Modified code"),
01020             tr("The source code has been modified.\nDo you want to save your changes?"),
01021             QMessageBox::Yes | QMessageBox::Default,
01022             QMessageBox::No,
01023             QMessageBox::Cancel | QMessageBox::Escape);
01024         if (ret == QMessageBox::Yes) {
01025             return saveSourceFile();
01026         }
01027         else if (ret == QMessageBox::Cancel) {
01028             return false;
01029         }
01030     }
01031     return true;
01032 }
01033 
01034 
01039 void MainWindow::languageChanged(int languageIndex) {
01040     if ( languageIndex < _settings->getAvailableTranslations().size() ) {
01041         // Get the mnemonic of the new selected language.
01042         QString languageShort = _settings->getAvailableTranslations().at(languageIndex);
01043 
01044         // Remove the old qt translation.
01045         qApp->removeTranslator( _qTTranslator );
01046 
01047         // Remove the old uigui translation.
01048         qApp->removeTranslator( _uiGuiTranslator );
01049 
01050         // Load the Qt own translation file and set it for the application.
01051         bool translationFileLoaded;
01052         translationFileLoaded = _qTTranslator->load( SettingsPaths::getGlobalFilesPath() + "/translations/qt_" + languageShort );
01053         if ( translationFileLoaded ) {
01054             qApp->installTranslator(_qTTranslator);
01055         }
01056 
01057         // Load the uigui translation file and set it for the application.
01058         translationFileLoaded = _uiGuiTranslator->load( SettingsPaths::getGlobalFilesPath() + "/translations/universalindent_" + languageShort );
01059         if ( translationFileLoaded ) {
01060             qApp->installTranslator(_uiGuiTranslator);
01061         }
01062     }
01063 }
01064 
01065 
01069 void MainWindow::createEncodingMenu() {
01070     QAction *encodingAction;
01071     QString encodingName;
01072 
01073     _encodingsList = QStringList() << "UTF-8" << "UTF-16" << "UTF-16BE" << "UTF-16LE"
01074         << "Apple Roman" << "Big5" << "Big5-HKSCS" << "EUC-JP" << "EUC-KR" << "GB18030-0"
01075         << "IBM 850" << "IBM 866" << "IBM 874" << "ISO 2022-JP" << "ISO 8859-1" << "ISO 8859-13"
01076         << "Iscii-Bng" << "JIS X 0201" << "JIS X 0208" << "KOI8-R" << "KOI8-U" << "MuleLao-1"
01077         << "ROMAN8" << "Shift-JIS" << "TIS-620" << "TSCII" << "Windows-1250" << "WINSAMI2";
01078 
01079     _encodingActionGroup = new QActionGroup(this);
01080     _saveEncodedActionGroup = new QActionGroup(this);
01081 
01082     // Loop for each available encoding
01083     foreach ( encodingName, _encodingsList ) {
01084         // Create actions for the "reopen" menu
01085         encodingAction = new QAction(encodingName, _encodingActionGroup);
01086         encodingAction->setStatusTip( tr("Reopen the currently opened source code file by using the text encoding scheme ") + encodingName );
01087         encodingAction->setCheckable(true);
01088         if ( encodingName == _currentEncoding ) {
01089             encodingAction->setChecked(true);
01090         }
01091 
01092         // Create actions for the "save as encoded" menu
01093         encodingAction = new QAction(encodingName, _saveEncodedActionGroup);
01094         encodingAction->setStatusTip( tr("Save the currently opened source code file by using the text encoding scheme ") + encodingName );
01095     }
01096 
01097     _mainWindowForm->encodingMenu->addActions( _encodingActionGroup->actions() );
01098     connect( _encodingActionGroup, SIGNAL(triggered(QAction*)), this, SLOT(encodingChanged(QAction*)) );
01099 
01100     _mainWindowForm->saveEncodedMenu->addActions( _saveEncodedActionGroup->actions() );
01101     connect( _saveEncodedActionGroup, SIGNAL(triggered(QAction*)), this, SLOT(saveAsOtherEncoding(QAction*)) );
01102 }
01103 
01104 
01111 void MainWindow::saveAsOtherEncoding(QAction *chosenEncodingAction) {
01112     bool fileWasSaved = saveasSourceFileDialog(chosenEncodingAction);
01113 
01114     // If the file was save with another encoding, change the selected encoding in the reopen menu.
01115     if ( fileWasSaved ) {
01116         foreach ( QAction *action, _encodingActionGroup->actions() ) {
01117             if ( action->text() == chosenEncodingAction->text() ) {
01118                 action->setChecked(true);
01119                 return;
01120             }
01121         }
01122     }
01123 }
01124 
01125 
01129 void MainWindow::encodingChanged(QAction* encodingAction) {
01130     if ( maybeSave() ) {
01131         QFile inSrcFile(_currentSourceFile);
01132         QString fileContent = "";
01133 
01134         if ( !inSrcFile.open(QFile::ReadOnly | QFile::Text) ) {
01135             QMessageBox::warning(NULL, tr("Error opening file"), tr("Cannot read the file ")+"\""+_currentSourceFile+"\"." );
01136         }
01137         else {
01138             QTextStream inSrcStrm(&inSrcFile);
01139             QApplication::setOverrideCursor(Qt::WaitCursor);
01140             QString encodingName = encodingAction->text();
01141             _currentEncoding = encodingName;
01142             inSrcStrm.setCodec( QTextCodec::codecForName(encodingName.toAscii()) );
01143             fileContent = inSrcStrm.readAll();
01144             QApplication::restoreOverrideCursor();
01145             inSrcFile.close();
01146             _qSciSourceCodeEditor->setText( fileContent );
01147             _qSciSourceCodeEditor->setModified(false);
01148         }
01149     }
01150 }
01151 
01152 
01156 void MainWindow::createHighlighterMenu() {
01157     QAction *highlighterAction;
01158     QString highlighterName;
01159 
01160     _highlighterActionGroup = new QActionGroup(this);
01161 
01162     // Loop for each known highlighter
01163     foreach ( highlighterName, _highlighter->getAvailableHighlighters() ) {
01164         highlighterAction = new QAction(highlighterName, _highlighterActionGroup);
01165         highlighterAction->setStatusTip( tr("Set the syntax highlightning to ") + highlighterName );
01166         highlighterAction->setCheckable(true);
01167     }
01168     _mainWindowForm->highlighterMenu->addActions( _highlighterActionGroup->actions() );
01169     _mainWindowForm->menuSettings->insertMenu(_mainWindowForm->indenterParameterTooltipsEnabledAction, _mainWindowForm->highlighterMenu );
01170 
01171     connect( _highlighterActionGroup, SIGNAL(triggered(QAction*)), _highlighter, SLOT(setHighlighterByAction(QAction*)) );
01172 }
01173 
01174 
01178 void MainWindow::setWhiteSpaceVisibility(bool visible) {
01179     if ( _qSciSourceCodeEditor != NULL ) {
01180         if ( visible ) {
01181             _qSciSourceCodeEditor->setWhitespaceVisibility(QsciScintilla::WsVisible);
01182         }
01183         else {
01184             _qSciSourceCodeEditor->setWhitespaceVisibility(QsciScintilla::WsInvisible);
01185         }
01186     }
01187 }
01188 
01193 void MainWindow::numberOfLinesChanged() {
01194     QString lineNumbers;
01195     lineNumbers.setNum( _qSciSourceCodeEditor->lines()*10 );
01196     _qSciSourceCodeEditor->setMarginWidth(1, lineNumbers);
01197 }
01198 
01199 
01203 void MainWindow::changeEvent(QEvent *event) {
01204     int i = 0;
01205 
01206     if (event->type() == QEvent::LanguageChange) {
01207         QString languageName;
01208 
01209         // Translate the main window.
01210         _mainWindowForm->retranslateUi(this);
01211         updateWindowTitle();
01212 
01213         // Translate the toolbar.
01214         _toolBarWidget->retranslateUi(_mainWindowForm->toolBar);
01215 
01216         // Translate the indent handler widget.
01217         _indentHandler->retranslateUi();
01218 
01219         // Translate the load encoding menu.
01220         QList<QAction *> encodingActionList = _encodingActionGroup->actions();
01221         for ( i = 0; i < encodingActionList.size(); i++ ) {
01222             encodingActionList.at(i)->setStatusTip( tr("Reopen the currently opened source code file by using the text encoding scheme ") + _encodingsList.at(i) );
01223         }
01224 
01225         // Translate the save encoding menu.
01226         encodingActionList = _saveEncodedActionGroup->actions();
01227         for ( i = 0; i < encodingActionList.size(); i++ ) {
01228             encodingActionList.at(i)->setStatusTip( tr("Save the currently opened source code file by using the text encoding scheme ") + _encodingsList.at(i) );
01229         }
01230 
01231         // Translate the _highlighter menu.
01232         QList<QAction *> actionList = _mainWindowForm->highlighterMenu->actions();
01233         i = 0;
01234         foreach ( QString highlighterName, _highlighter->getAvailableHighlighters() ) {
01235             QAction *highlighterAction = actionList.at(i);
01236             highlighterAction->setStatusTip( tr("Set the syntax highlightning to ") + highlighterName );
01237             i++;
01238         }
01239 
01240         // Translate the line and column indicators in the statusbar.
01241         int line, column;
01242         _qSciSourceCodeEditor->getCursorPosition( &line, &column );
01243         setStatusBarCursorPosInfo( line, column );
01244     }
01245     else {
01246         QWidget::changeEvent(event);
01247     }
01248 }
01249 
01250 
01251 
01260 void MainWindow::updateRecentlyOpenedList() {
01261     QString fileName;
01262     QString filePath;
01263     QStringList recentlyOpenedList = _settings->getValueByName("lastSourceCodeFile").toString().split("|");
01264     QList<QAction*> recentlyOpenedActionList = _mainWindowForm->menuRecently_Opened_Files->actions();
01265 
01266     // Check if the currently open file is in the list of recently opened.
01267     int indexOfCurrentFile = recentlyOpenedList.indexOf( _currentSourceFile );
01268 
01269     // If it is in the list of recently opened files and not at the first position, move it to the first pos.
01270     if ( indexOfCurrentFile > 0 ) {
01271         recentlyOpenedList.move(indexOfCurrentFile, 0);
01272         recentlyOpenedActionList.move(indexOfCurrentFile, 0);
01273     }
01274     // Put the current file at the first position if it not already is and is not empty.
01275     else if ( indexOfCurrentFile == -1 && !_currentSourceFile.isEmpty() ) {
01276         recentlyOpenedList.insert(0, _currentSourceFile);
01277         QAction *recentlyOpenedAction = new QAction(QFileInfo(_currentSourceFile).fileName(), _mainWindowForm->menuRecently_Opened_Files);
01278         recentlyOpenedAction->setStatusTip(_currentSourceFile);
01279         recentlyOpenedActionList.insert(0, recentlyOpenedAction );
01280     }
01281 
01282     // Get the maximum recently opened list size.
01283     int recentlyOpenedListMaxSize = _settings->getValueByName("recentlyOpenedListSize").toInt();
01284 
01285     // Loop for each filepath in the recently opened list, remove non existing files and
01286     // loop only as long as maximum allowed list entries are set.
01287     for ( int i = 0; i < recentlyOpenedList.size() && i < recentlyOpenedListMaxSize; ) {
01288         filePath = recentlyOpenedList.at(i);
01289         QFileInfo fileInfo(filePath);
01290 
01291         // If the file does no longer exist, remove it from the list.
01292         if ( !fileInfo.exists() ) {
01293             recentlyOpenedList.takeAt(i);
01294             if ( i < recentlyOpenedActionList.size()-2 ) {
01295                 QAction* action = recentlyOpenedActionList.takeAt(i);
01296                 delete action;
01297             }
01298         }
01299         // else if its not already in the menu, add it to the menu.
01300         else {
01301             if ( i >= recentlyOpenedActionList.size()-2 ) {
01302                 QAction *recentlyOpenedAction = new QAction(fileInfo.fileName(), _mainWindowForm->menuRecently_Opened_Files);
01303                 recentlyOpenedAction->setStatusTip(filePath);
01304                 recentlyOpenedActionList.insert( recentlyOpenedActionList.size()-2, recentlyOpenedAction );
01305             }
01306             i++;
01307         }
01308     }
01309 
01310     // Trim the list to its in the _settings allowed maximum size.
01311     while ( recentlyOpenedList.size() > recentlyOpenedListMaxSize ) {
01312         recentlyOpenedList.takeLast();
01313         QAction* action = recentlyOpenedActionList.takeAt( recentlyOpenedActionList.size()-3 );
01314         delete action;
01315     }
01316 
01317     // Add all actions to the menu.
01318     _mainWindowForm->menuRecently_Opened_Files->addActions(recentlyOpenedActionList);
01319     _mainWindowForm->menuRecently_Opened_Files->addActions(recentlyOpenedActionList);
01320 
01321     // Write the new recently opened list to the _settings.
01322     _settings->setValueByName( "lastSourceCodeFile", recentlyOpenedList.join("|") );
01323 
01324     // Enable or disable "actionClear_Recently_Opened_List" if list is [not] emtpy
01325     if ( recentlyOpenedList.isEmpty() ) {
01326         _mainWindowForm->actionClear_Recently_Opened_List->setEnabled(false);
01327     }
01328     else {
01329         _mainWindowForm->actionClear_Recently_Opened_List->setEnabled(true);
01330     }
01331 }
01332 
01333 
01337 void MainWindow::clearRecentlyOpenedList() {
01338     QStringList recentlyOpenedList = _settings->getValueByName("lastSourceCodeFile").toString().split("|");
01339     QList<QAction*> recentlyOpenedActionList = _mainWindowForm->menuRecently_Opened_Files->actions();
01340 
01341     while ( recentlyOpenedList.size() > 0 ) {
01342         recentlyOpenedList.takeLast();
01343         QAction* action = recentlyOpenedActionList.takeAt( recentlyOpenedActionList.size()-3 );
01344         delete action;
01345     }
01346 
01347     // Write the new recently opened list to the _settings.
01348     _settings->setValueByName( "lastSourceCodeFile", recentlyOpenedList.join("|") );
01349 
01350     // Disable "actionClear_Recently_Opened_List"
01351     _mainWindowForm->actionClear_Recently_Opened_List->setEnabled(false);
01352 }
01353 
01354 
01359 void MainWindow::openFileFromRecentlyOpenedList(QAction* recentlyOpenedAction) {
01360     // If the selected action from the recently opened list menu is the clear action
01361     // call the slot to clear the list and then leave.
01362     if ( recentlyOpenedAction == _mainWindowForm->actionClear_Recently_Opened_List ) {
01363         clearRecentlyOpenedList();
01364         return;
01365     }
01366 
01367     QString fileName = recentlyOpenedAction->text();
01368     int indexOfSelectedFile = _mainWindowForm->menuRecently_Opened_Files->actions().indexOf( recentlyOpenedAction );
01369     QStringList recentlyOpenedList = _settings->getValueByName("lastSourceCodeFile").toString().split("|");
01370     QString filePath = recentlyOpenedList.at(indexOfSelectedFile);
01371     QFileInfo fileInfo(filePath);
01372 
01373     // If the file exists, open it.
01374     if ( fileInfo.exists() ) {
01375         openSourceFileDialog(filePath);
01376     }
01377     // If it does not exist, show a warning message and update the list of recently opened files.
01378     else {
01379         QMessageBox::warning(NULL, tr("File no longer exists"), tr("The file %1 in the list of recently opened files does no longer exist.") );
01380         // The function updateRecentlyOpenedList() has to be called via a singleShot so it is executed after this
01381         // function (openFileFromRecentlyOpenedList) has already been left. This has to be done because
01382         // a Qt3Support function tries to emit a signal based on the existing actions and deleting
01383         // any of these actions in updateRecentlyOpenedList() causes an error.
01384         QTimer::singleShot(0, this, SLOT(updateRecentlyOpenedList()) );
01385     }
01386 }
01387 
01388 
01392 void MainWindow::dragEnterEvent(QDragEnterEvent *event) {
01393     if ( event->mimeData()->hasUrls() ) {
01394         event->acceptProposedAction();
01395     }
01396 }
01397 
01398 
01402 void MainWindow::dropEvent(QDropEvent *event) {
01403     if ( event->mimeData()->hasUrls() ) {
01404         QString filePathName = event->mimeData()->urls().first().toLocalFile();
01405         openSourceFileDialog(filePathName);
01406     }
01407 
01408     event->acceptProposedAction();
01409 }
01410 
01411 
01415 void MainWindow::showAboutDialog() {
01416     //QPixmap originalPixmap = QPixmap::grabWindow(QApplication::desktop()->screen()->winId());
01417     //qDebug("in main pixmap width %d, numScreens = %d", originalPixmap.size().width(), QApplication::desktop()->availableGeometry().width());
01418     //_aboutDialogGraphicsView->setScreenshotPixmap( originalPixmap );
01419     _aboutDialogGraphicsView->show();
01420 }
01421 
01422 
01426 void MainWindow::setStatusBarCursorPosInfo( int line, int column ) {
01427     _textEditLineColumnInfoLabel->setText( tr("Line %1, Column %2").arg(line+1).arg(column+1) );
01428 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines