diff --git a/RedPandaIDE/RedPandaIDE.pro b/RedPandaIDE/RedPandaIDE.pro index 1765af11..8b4d650c 100644 --- a/RedPandaIDE/RedPandaIDE.pro +++ b/RedPandaIDE/RedPandaIDE.pro @@ -14,6 +14,7 @@ SOURCES += \ main.cpp \ mainwindow.cpp \ settings.cpp \ + systemconsts.cpp \ utils.cpp HEADERS += \ @@ -21,6 +22,7 @@ HEADERS += \ editorlist.h \ mainwindow.h \ settings.h \ + systemconsts.h \ utils.h FORMS += \ diff --git a/RedPandaIDE/editor.cpp b/RedPandaIDE/editor.cpp index 1f1ad239..a4684e9f 100644 --- a/RedPandaIDE/editor.cpp +++ b/RedPandaIDE/editor.cpp @@ -8,6 +8,7 @@ #include #include "settings.h" #include "mainwindow.h" +#include "systemconsts.h" #include #include #include @@ -15,6 +16,19 @@ using namespace std; +SaveException::SaveException(const QString& reason) { + mReason = reason; +} +SaveException::SaveException(const QString&& reason) { + mReason = reason; +} +const QString& SaveException::reason() const noexcept{ + return mReason; +} +const char *SaveException::what() const noexcept { + return mReason.toLocal8Bit(); +} + Editor::Editor(QWidget *parent, const QString& filename, const QByteArray& encoding, @@ -92,6 +106,8 @@ Editor::Editor(QWidget *parent, const QString& filename, this, SLOT(onCursorPositionChanged(int,int))); connect(this, SIGNAL(linesChanged()), this,SLOT(onLinesChanged())); + + this->toggleComment } Editor::~Editor() { @@ -107,7 +123,13 @@ Editor::~Editor() { void Editor::loadFile() { QFile file(mFilename); - QByteArray content=file.read(file.bytesAvailable()); + if (!file.open(QFile::ReadOnly)) { + QMessageBox::information(pMainWindow, + tr("Error"), + QString(tr("Can't Open File %1:%2")).arg(mFilename).arg(file.errorString())); + } + QByteArray content=file.readAll(); + file.close(); if (mEncodingOption == ENCODING_AUTO_DETECT) { mFileEncoding = GuessTextEncoding(content); } else { @@ -119,6 +141,8 @@ void Editor::loadFile() { this->setText(QString::fromUtf8(content.mid(3))); } else if (mFileEncoding == ENCODING_ASCII) { this->setText(QString::fromLatin1(content)); + } else if (mFileEncoding == ENCODING_SYSTEM_DEFAULT) { + this->setText(QString::fromLocal8Bit(content)); }else { QTextCodec*codec = QTextCodec::codecForName(mFileEncoding); this->setText(codec->toUnicode(content)); @@ -148,30 +172,42 @@ void Editor::saveFile(const QString &filename) { ba.append(this->text().toUtf8()); } else if (mFileEncoding == ENCODING_ASCII) { ba = this->text().toLatin1(); + } else if (mFileEncoding == ENCODING_SYSTEM_DEFAULT) { + ba = this->text().toLocal8Bit(); } else { QTextCodec* codec = QTextCodec::codecForName(mFileEncoding); ba = codec->fromUnicode(this->text()); } - file.open(QFile::WriteOnly); - file.write(ba); - file.close(); + if (file.open(QFile::WriteOnly)) { + if (file.write(ba)<0) { + throw SaveException(QString(tr("Failed to Save file %1: %2")).arg(filename).arg(file.errorString())); + } + file.close(); + } else { + throw SaveException(QString(tr("Failed to Open file %1: %2")).arg(filename).arg(file.errorString())); + } } bool Editor::save(bool force, bool reparse) { if (this->mIsNew) { return saveAs(); } - QFile file(mFilename); QFileInfo info(mFilename); + //is this file writable; if (!force && !info.isWritable()) { QMessageBox::information(pMainWindow,tr("Fail"), QString(QObject::tr("File %s is not writable!"))); return false; } - //is this file read-only? if (this->isModified() || force) { - saveFile(mFilename); - setModified(false); + try { + saveFile(mFilename); + setModified(false); + } catch (SaveException& exception) { + QMessageBox::information(pMainWindow,tr("Fail"), + exception.reason()); + return false; + } } if (reparse) { @@ -181,15 +217,23 @@ bool Editor::save(bool force, bool reparse) { } bool Editor::saveAs(){ + QString selectedFileFilter = pSystemConsts->defaultFileFilter(); QString newName = QFileDialog::getSaveFileName(pMainWindow, - tr("Save As")); + tr("Save As"), QString(), pSystemConsts->defaultFileFilters().join(";;"), + &selectedFileFilter); if (newName.isEmpty()) { return false; } - saveFile(newName); - mFilename = newName; - mIsNew = false; - setModified(false); + try { + saveFile(mFilename); + mFilename = newName; + mIsNew = false; + setModified(false); + } catch (SaveException& exception) { + QMessageBox::information(pMainWindow,tr("Fail"), + exception.reason()); + return false; + } //todo: update (reassign highlighter) //todo: remove old file from parser and reparse file @@ -199,26 +243,26 @@ bool Editor::saveAs(){ return true; } -const QByteArray& Editor::encodingOption() const { +const QByteArray& Editor::encodingOption() const noexcept{ return mEncodingOption; } -void Editor::setEncodingOption(const QByteArray& encoding) { +void Editor::setEncodingOption(const QByteArray& encoding) noexcept{ mEncodingOption = encoding; } -const QByteArray& Editor::fileEncoding() const { +const QByteArray& Editor::fileEncoding() const noexcept{ return mFileEncoding; } -const QString& Editor::filename() { +const QString& Editor::filename() const noexcept{ return mFilename; } -bool Editor::inProject() const { +bool Editor::inProject() const noexcept{ return mInProject; } -bool Editor::isNew() const { +bool Editor::isNew() const noexcept { return mIsNew; } -QTabWidget* Editor::pageControl() { +QTabWidget* Editor::pageControl() noexcept{ return mParentPageControl; } @@ -232,17 +276,15 @@ void Editor::wheelEvent(QWheelEvent *event) { } } -void Editor::onModificationChanged(bool status) { +void Editor::onModificationChanged(bool) { updateCaption(); } -void Editor::onCursorPositionChanged(int line, int index) -{ +void Editor::onCursorPositionChanged(int line, int index) { pMainWindow->updateStatusBarForEditingInfo(line,index+1,lines(),text().length()); } -void Editor::onLinesChanged() -{ +void Editor::onLinesChanged() { qDebug()<<"lala"< #include +class SaveException: public std::exception { + +public: + explicit SaveException(const QString& reason); + explicit SaveException(const QString&& reason); + // exception interface + const QString& reason() const noexcept; +public: + const char *what() const noexcept override; +private: + QString mReason; +}; + class Editor : public QsciScintilla { Q_OBJECT @@ -22,19 +35,19 @@ public: Editor& operator=(const Editor&) = delete; Editor& operator=(const Editor&&) = delete; - const QByteArray& encodingOption() const; - void setEncodingOption(const QByteArray& encoding); - const QByteArray& fileEncoding() const; - const QString& filename(); - bool inProject() const; - bool isNew() const; + const QByteArray& encodingOption() const noexcept; + void setEncodingOption(const QByteArray& encoding) noexcept; + const QByteArray& fileEncoding() const noexcept; + const QString& filename() const noexcept; + bool inProject() const noexcept; + bool isNew() const noexcept; void loadFile(); void saveFile(const QString& filename); bool save(bool force=false, bool reparse=true); bool saveAs(); - QTabWidget* pageControl(); + QTabWidget* pageControl() noexcept; void updateCaption(const QString& newCaption=QString()); @@ -42,9 +55,9 @@ signals: protected slots: - void onModificationChanged(bool status); - void onCursorPositionChanged(int line, int index); - void onLinesChanged(); + void onModificationChanged(bool status) ; + void onCursorPositionChanged(int line, int index) ; + void onLinesChanged() ; private: QByteArray mEncodingOption; // the encoding type set by the user diff --git a/RedPandaIDE/editorlist.cpp b/RedPandaIDE/editorlist.cpp index e66dd8c9..57987a9f 100644 --- a/RedPandaIDE/editorlist.cpp +++ b/RedPandaIDE/editorlist.cpp @@ -123,3 +123,20 @@ bool EditorList::closeAll(bool force) { return true; } + +Editor* EditorList::findOpenedEditor(const QString &filename) +{ + for (int i=0;icount();i++) { + Editor* e = static_cast(mLeftPageWidget->widget(i)); + if (e->filename() == filename) { + return e; + } + } + for (int i=0;icount();i++) { + Editor* e = static_cast(mRightPageWidget->widget(i)); + if (e->filename() == filename) { + return e; + } + } + return nullptr; +} diff --git a/RedPandaIDE/editorlist.h b/RedPandaIDE/editorlist.h index 036a9c3a..953f40a4 100644 --- a/RedPandaIDE/editorlist.h +++ b/RedPandaIDE/editorlist.h @@ -40,6 +40,8 @@ public: bool closeAll(bool force = false); + Editor* findOpenedEditor(const QString& filename); + void beginUpdate(); void endUpdate(); diff --git a/RedPandaIDE/main.cpp b/RedPandaIDE/main.cpp index 3ffa97a2..bb5b2059 100644 --- a/RedPandaIDE/main.cpp +++ b/RedPandaIDE/main.cpp @@ -1,14 +1,17 @@ #include "mainwindow.h" #include "settings.h" +#include "systemconsts.h" #include int main(int argc, char *argv[]) { - QApplication a(argc, argv); - Settings s; - pSettings = &s; - MainWindow w; - pMainWindow = &w; - w.show(); - return a.exec(); + QApplication app(argc, argv); + SystemConsts systemConsts; + pSystemConsts = &systemConsts; + Settings settings; + pSettings = &settings; + MainWindow mainWindow; + pMainWindow = &mainWindow; + mainWindow.show(); + return app.exec(); } diff --git a/RedPandaIDE/mainwindow.cpp b/RedPandaIDE/mainwindow.cpp index 69ca75c4..0a01530f 100644 --- a/RedPandaIDE/mainwindow.cpp +++ b/RedPandaIDE/mainwindow.cpp @@ -2,8 +2,11 @@ #include "ui_mainwindow.h" #include "editorlist.h" #include "editor.h" +#include "systemconsts.h" +#include "settings.h" #include +#include #include MainWindow* pMainWindow; @@ -50,6 +53,28 @@ void MainWindow::updateStatusBarForEditingInfo(int line,int col,int lines,int ch } } +void MainWindow::openFiles(const QStringList &files) +{ + mEditorList->beginUpdate(); + for (QString file:files) { + openFile(file); + } + mEditorList->endUpdate(); +} + +void MainWindow::openFile(const QString &filename) +{ + Editor* editor = mEditorList->findOpenedEditor(filename); + if (editor!=nullptr) { + editor->setFocus(); + return; + } + editor = mEditorList->newEditor(filename,ENCODING_AUTO_DETECT, + false,false); + editor->setFocus(); + this->updateStatusBarForEncoding(); +} + void MainWindow::setupActions() { } @@ -69,10 +94,11 @@ void MainWindow::on_EditorTabsLeft_tabCloseRequested(int index) void MainWindow::on_actionOpen_triggered() { - Editor * editor = mEditorList->getEditor(); - if (editor != NULL) { - //editor->save(); - } + QString selectedFileFilter = pSystemConsts->defaultFileFilter(); + QStringList files = QFileDialog::getOpenFileNames(pMainWindow, + tr("Open"), QString(), pSystemConsts->defaultFileFilters().join(";;"), + &selectedFileFilter); + openFiles(files); } void MainWindow::closeEvent(QCloseEvent *event) { diff --git a/RedPandaIDE/mainwindow.h b/RedPandaIDE/mainwindow.h index 903c1064..a85e675f 100644 --- a/RedPandaIDE/mainwindow.h +++ b/RedPandaIDE/mainwindow.h @@ -21,7 +21,9 @@ public: void updateStatusBarForEncoding(); void updateStatusBarForEditingInfo(int line,int col,int lines,int charCount); - +protected: + void openFiles(const QStringList& files); + void openFile(const QString& filename); private slots: void on_actionNew_triggered(); diff --git a/RedPandaIDE/mainwindow.ui b/RedPandaIDE/mainwindow.ui index fe4d886b..eb6a633f 100644 --- a/RedPandaIDE/mainwindow.ui +++ b/RedPandaIDE/mainwindow.ui @@ -222,6 +222,9 @@ New + + Ctrl+N + @@ -232,6 +235,9 @@ Open... + + Ctrl+O + @@ -242,6 +248,9 @@ Save + + Ctrl+S + @@ -265,6 +274,9 @@ Save All + + Ctrl+Shift+S + diff --git a/RedPandaIDE/systemconsts.cpp b/RedPandaIDE/systemconsts.cpp new file mode 100644 index 00000000..78bf30a1 --- /dev/null +++ b/RedPandaIDE/systemconsts.cpp @@ -0,0 +1,30 @@ +#include "systemconsts.h" +#include +#include +#include + +SystemConsts* pSystemConsts; + +SystemConsts::SystemConsts(): mDefaultFileFilters() +{ + addDefaultFileFilter(QObject::tr("C files"),"*.c"); + addDefaultFileFilter(QObject::tr("C++ files"),"*.cpp *.cc *.cxx"); + addDefaultFileFilter(QObject::tr("Header files"),"*.h *.hh"); + addDefaultFileFilter(QObject::tr("Text files"),"*.txt"); + addDefaultFileFilter(QObject::tr("All files"),"*"); +} + +const QStringList &SystemConsts::defaultFileFilters() const noexcept +{ + return mDefaultFileFilters; +} + +const QString &SystemConsts::defaultFileFilter() const noexcept +{ + return mDefaultFileFilters[1]; +} + +void SystemConsts::addDefaultFileFilter(const QString &name, const QString &fileExtensions) +{ + mDefaultFileFilters.append(name+ " (" + fileExtensions+")"); +} diff --git a/RedPandaIDE/systemconsts.h b/RedPandaIDE/systemconsts.h new file mode 100644 index 00000000..1db0c64f --- /dev/null +++ b/RedPandaIDE/systemconsts.h @@ -0,0 +1,18 @@ +#ifndef SYSTEMCONSTS_H +#define SYSTEMCONSTS_H + +#include + +class SystemConsts +{ +public: + SystemConsts(); + const QStringList& defaultFileFilters() const noexcept; + const QString& defaultFileFilter() const noexcept; + void addDefaultFileFilter(const QString& name, const QString& fileExtensions); +private: + QStringList mDefaultFileFilters; +}; + +extern SystemConsts* pSystemConsts; +#endif // SYSTEMCONSTS_H