Page MenuHomePhabricator (Chris)

No OneTemporary

Authored By
Unknown
Size
17 KB
Referenced Files
None
Subscribers
None
diff --git a/extra/TextEditor/TextEditor.pro b/extra/TextEditor/TextEditor.pro
new file mode 100644
index 0000000..65ec319
--- /dev/null
+++ b/extra/TextEditor/TextEditor.pro
@@ -0,0 +1,51 @@
+#-------------------------------------------------
+#
+# Project created by QtCreator 2016-03-14T22:31:35
+#
+#-------------------------------------------------
+
+QT += core gui widgets
+
+CONFIG += c++11
+TARGET = TextEditor
+TEMPLATE = app
+
+unix:QMAKE_CXXFLAGS += -Wall -Wextra -Werror=return-type -Werror=trigraphs -Wno-switch -Wno-reorder
+
+INCLUDEPATH += $$PWD/src
+INCLUDEPATH += $$PWD/../../src/texteditor
+INCLUDEPATH += $$PWD/../../src
+
+linux:LIBS += -lncursesw
+macx:LIBS += -lncurses
+
+SOURCES += \
+ $$PWD/../../src/common/joinpath.cpp \
+ $$PWD/../../src/common/misc.cpp \
+ $$PWD/../../src/texteditor/AbstractCharacterBasedApplication.cpp \
+ $$PWD/../../src/texteditor/InputMethodPopup.cpp \
+ $$PWD/../../src/texteditor/TextEditorTheme.cpp \
+ $$PWD/../../src/texteditor/TextEditorWidget.cpp \
+ $$PWD/../../src/texteditor/UnicodeWidth.cpp \
+ $$PWD/../../src/texteditor/unicode.cpp \
+ src/MainWindow.cpp \
+ src/MySettings.cpp \
+ src/main.cpp\
+ src/cmain.cpp
+
+HEADERS += \
+ $$PWD/../../src/common/joinpath.h \
+ $$PWD/../../src/common/misc.h \
+ $$PWD/../../src/texteditor/AbstractCharacterBasedApplication.h \
+ $$PWD/../../src/texteditor/InputMethodPopup.h \
+ $$PWD/../../src/texteditor/TextEditorTheme.h \
+ $$PWD/../../src/texteditor/TextEditorWidget.h \
+ $$PWD/../../src/texteditor/UnicodeWidth.h \
+ $$PWD/../../src/texteditor/unicode.h \
+ src/MainWindow.h \
+ src/MySettings.h \
+ src/cmain.h
+
+FORMS += \
+ src/MainWindow.ui
+
diff --git a/extra/TextEditor/src/MainWindow.cpp b/extra/TextEditor/src/MainWindow.cpp
new file mode 100644
index 0000000..48ad516
--- /dev/null
+++ b/extra/TextEditor/src/MainWindow.cpp
@@ -0,0 +1,169 @@
+
+#include "MainWindow.h"
+#include "MySettings.h"
+#include "ui_MainWindow.h"
+
+#include <QDebug>
+#include <QKeyEvent>
+#include <QPainter>
+#include <QTextFormat>
+#include <QFileDialog>
+#include <QTimer>
+
+
+struct MainWindow::Private {
+ bool need_to_layout;
+ QRect cursor_rect;
+ TextEditorEnginePtr engine;
+ QString last_used_file;
+ QTimer tm;
+};
+
+MainWindow::MainWindow(QWidget *parent)
+ : QMainWindow(parent)
+ , ui(new Ui::MainWindow)
+ , m(new Private)
+{
+ ui->setupUi(this);
+ auto flags = windowFlags();
+ flags &= ~Qt::WindowMaximizeButtonHint;
+ flags |= Qt::MSWindowsFixedSizeDialogHint;
+ setWindowFlags(flags);
+ m->need_to_layout = true;
+
+ ui->widget->setTheme(TextEditorTheme::Dark());
+
+// setFont(ui->widget->font());
+
+ m->engine = TextEditorEnginePtr(new TextEditorEngine);
+ ui->widget->setTextEditorEngine(m->engine);
+
+ if (1) {
+ ui->widget->setNormalTextEditorMode(true);
+ } else {
+ ui->widget->setTerminalMode(true);
+ }
+
+ ui->widget->bindScrollBar(ui->verticalScrollBar, ui->horizontalScrollBar);
+// ui->widget->setReadOnly(true);
+
+ ui->widget->setWriteMode(AbstractCharacterBasedApplication::WriteMode::Insert);
+
+ connect(&m->tm, SIGNAL(timeout()), this, SLOT(updateIm()));
+}
+
+MainWindow::~MainWindow()
+{
+ delete m;
+ delete ui;
+}
+
+void MainWindow::keyPressEvent(QKeyEvent *e)
+{
+ ui->widget->write(e);
+
+ if (ui->widget->state() == TextEditorWidget::State::Exit) {
+ close();
+ }
+}
+
+bool MainWindow::event(QEvent *e)
+{
+ bool r = QMainWindow::event(e);
+ if (e->type() == QEvent::WindowActivate) {
+ if (m->need_to_layout) {
+ m->need_to_layout = false;
+ int w = ui->widget->latin1Width() * ui->widget->screenWidth();
+ int h = ui->widget->lineHeight() * ui->widget->screenHeight();
+ int sb = style()->pixelMetric(QStyle::PM_ScrollBarExtent);
+ w += sb;
+ h += sb;
+ h += ui->menuBar->height();
+ setFixedSize(w, h);
+ }
+ }
+ return r;
+}
+
+TextEditorEnginePtr MainWindow::engine()
+{
+ return m->engine;
+}
+
+Document *MainWindow::document()
+{
+ return &engine()->document;
+}
+
+void MainWindow::upArrow()
+{
+ ui->widget->moveCursorUp();
+}
+
+void MainWindow::downArrow()
+{
+ ui->widget->moveCursorDown();
+}
+
+void MainWindow::leftArrow()
+{
+ ui->widget->moveCursorLeft();
+}
+
+void MainWindow::rightArrow()
+{
+ ui->widget->moveCursorRight();
+}
+
+void MainWindow::on_verticalScrollBar_valueChanged(int /*value*/)
+{
+ ui->widget->refrectScrollBar();
+}
+
+void MainWindow::on_horizontalScrollBar_valueChanged(int /*value*/)
+{
+ ui->widget->refrectScrollBar();
+}
+
+void MainWindow::on_action_file_open_triggered()
+{
+ QString path;
+ {
+ MySettings s;
+ s.beginGroup("File");
+ path = s.value("LastUsedFile").toString();
+ }
+ path = QFileDialog::getOpenFileName(this, tr("Open"), path);
+ if (!path.isEmpty()) {
+ {
+ MySettings s;
+ s.beginGroup("File");
+ s.setValue("LastUsedFile", path);
+ }
+ ui->widget->openFile(path);
+ }
+}
+
+void MainWindow::on_action_file_save_triggered()
+{
+ ui->widget->saveFile("/tmp/test.txt");
+}
+
+void MainWindow::updateIm()
+{
+ QApplication::inputMethod()->update(Qt::ImCursorRectangle);
+}
+
+void MainWindow::moveEvent(QMoveEvent *)
+{
+ m->tm.stop();
+ m->tm.setSingleShot(true);
+ m->tm.start(100);
+}
+
+void MainWindow::on_action_test_triggered()
+{
+ std::string cmd = "\x1b[36mHello, \x1b[34mworld\n";
+ ui->widget->write(cmd);
+
+}
diff --git a/extra/TextEditor/src/MainWindow.h b/extra/TextEditor/src/MainWindow.h
new file mode 100644
index 0000000..bd44734
--- /dev/null
+++ b/extra/TextEditor/src/MainWindow.h
@@ -0,0 +1,52 @@
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include "texteditor/InputMethodPopup.h"
+
+#include <QMainWindow>
+
+namespace Ui {
+class MainWindow;
+}
+
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+
+private:
+ struct Private;
+ Private *m;
+public:
+ explicit MainWindow(QWidget *parent = 0);
+ ~MainWindow();
+
+private:
+ Ui::MainWindow *ui;
+
+ void upArrow();
+ void downArrow();
+ void leftArrow();
+ void rightArrow();
+
+ TextEditorEnginePtr engine();
+ Document *document();
+protected:
+ void keyPressEvent(QKeyEvent *);
+
+public:
+ bool event(QEvent *);
+
+private slots:
+ void on_verticalScrollBar_valueChanged(int value);
+ void on_horizontalScrollBar_valueChanged(int value);
+ void on_action_file_open_triggered();
+ void on_action_file_save_triggered();
+ void on_action_test_triggered();
+ void updateIm();
+protected:
+ void moveEvent(QMoveEvent *);
+signals:
+ void hoge();
+};
+
+#endif // MAINWINDOW_H
diff --git a/extra/TextEditor/src/MainWindow.ui b/extra/TextEditor/src/MainWindow.ui
new file mode 100644
index 0000000..9b93276
--- /dev/null
+++ b/extra/TextEditor/src/MainWindow.ui
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>593</width>
+ <height>436</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>MainWindow</string>
+ </property>
+ <widget class="QWidget" name="centralWidget">
+ <layout class="QGridLayout" name="gridLayout">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <item row="0" column="0">
+ <widget class="TextEditorWidget" name="widget" native="true">
+ <property name="focusPolicy">
+ <enum>Qt::StrongFocus</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QScrollBar" name="verticalScrollBar">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QScrollBar" name="horizontalScrollBar">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QMenuBar" name="menuBar">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>593</width>
+ <height>18</height>
+ </rect>
+ </property>
+ <widget class="QMenu" name="menu_File">
+ <property name="title">
+ <string>&amp;File</string>
+ </property>
+ <addaction name="action_file_open"/>
+ <addaction name="action_file_save"/>
+ <addaction name="action_test"/>
+ </widget>
+ <addaction name="menu_File"/>
+ </widget>
+ <action name="action_file_open">
+ <property name="text">
+ <string>&amp;Open...</string>
+ </property>
+ </action>
+ <action name="action_file_save">
+ <property name="text">
+ <string>&amp;Save</string>
+ </property>
+ </action>
+ <action name="action_test">
+ <property name="text">
+ <string>Test</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+T</string>
+ </property>
+ </action>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <customwidgets>
+ <customwidget>
+ <class>TextEditorWidget</class>
+ <extends>QWidget</extends>
+ <header>TextEditorWidget.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/extra/TextEditor/src/MySettings.cpp b/extra/TextEditor/src/MySettings.cpp
new file mode 100644
index 0000000..ae46591
--- /dev/null
+++ b/extra/TextEditor/src/MySettings.cpp
@@ -0,0 +1,22 @@
+#include "MySettings.h"
+#include <common/joinpath.h>
+#include <QApplication>
+#include <QDir>
+#include <QString>
+#include <QStandardPaths>
+
+QString makeApplicationDataDir()
+{
+ QString dir;
+ dir = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
+ if (!QFileInfo(dir).isDir()) {
+ QDir().mkpath(dir);
+ }
+ return dir;
+}
+
+MySettings::MySettings(QObject *)
+ : QSettings(joinpath(makeApplicationDataDir(), qApp->applicationName() + ".ini"), QSettings::IniFormat)
+{
+}
+
diff --git a/extra/TextEditor/src/MySettings.h b/extra/TextEditor/src/MySettings.h
new file mode 100644
index 0000000..1cb8710
--- /dev/null
+++ b/extra/TextEditor/src/MySettings.h
@@ -0,0 +1,22 @@
+#ifndef MYSETTINGS_H
+#define MYSETTINGS_H
+
+#include <QSettings>
+
+class MySettings : public QSettings
+{
+ Q_OBJECT
+public:
+ explicit MySettings(QObject *parent = 0);
+
+signals:
+
+public slots:
+
+};
+
+QString makeApplicationDataDir();
+
+extern char const *KEY_AutoReconnect;
+
+#endif // MYSETTINGS_H
diff --git a/extra/TextEditor/src/cmain.cpp b/extra/TextEditor/src/cmain.cpp
new file mode 100644
index 0000000..11f51d5
--- /dev/null
+++ b/extra/TextEditor/src/cmain.cpp
@@ -0,0 +1,309 @@
+
+#ifndef _WIN32
+
+#include <stdio.h>
+#include <unistd.h>
+#include <signal.h>
+#include <ncurses.h>
+#include <locale.h>
+#include <string>
+#include <vector>
+#include <AbstractCharacterBasedApplication.h>
+#include <string.h>
+#include <QtGlobal>
+#include <QDebug>
+#include "cmain.h"
+
+void siginthandler(int param)
+{
+}
+
+struct CursesOreApplication::Private {
+ int width;
+ int height;
+};
+
+CursesOreApplication::CursesOreApplication()
+ : m(new Private)
+{
+}
+
+CursesOreApplication::~CursesOreApplication()
+{
+ delete m;
+}
+
+int CursesOreApplication::screenWidth() const
+{
+ return m->width;
+}
+
+int CursesOreApplication::screenHeight() const
+{
+ return m->height;
+}
+
+
+
+void CursesOreApplication::clearLine(int y)
+{
+ std::vector<char> arr(y + 1);
+ std::fill(arr.begin(), arr.begin() + y, ' ');
+ arr[y] = 0;
+ mvprintw(y, 0, &arr[0]);
+}
+
+void CursesOreApplication::paintScreen()
+{
+ auto SetAttribute = [](CharAttr const &attr){
+ attr_t a = A_NORMAL;
+ if (attr.index == CharAttr::Invert) {
+ a = A_REVERSE;
+ }
+ attrset(a);
+ };
+ for (int y = 0; y < m->height; y++) {
+ if (line_flags()->at(y) & LineChanged) {
+ Character const *line = &screen()->at(m->width * y);
+ std::vector<char> vec;
+ vec.reserve(m->width * 3);
+ int x = 0;
+ int erase_x = 0;
+ int erase = 0;
+ auto Erase = [&](){
+ if (erase > 0) {
+ SetAttribute(CharAttr());
+ std::vector<char> vec;
+ vec.reserve(erase + 1);
+ vec.assign(erase, ' ');
+ vec.push_back(0);
+ move(y, erase_x);
+ waddnstr(stdscr, &vec[0], erase);
+ }
+ erase = 0;
+ };
+ while (x < m->width) {
+ CharAttr attr;
+ int n = 0;
+ QString text;
+ while (x + n < m->width) {
+ uint32_t c = line[x + n].c;
+ uint32_t d = 0;
+ if (c == 0 || c == 0xffff) {
+ break;
+ }
+ if ((c & 0xfc00) == 0xdc00) {
+ // surrogate 2nd
+ break;
+ }
+ uint32_t unicode = c;
+ if ((c & 0xfc00) == 0xd800) {
+ // surrogate 1st
+ if (x + n + 1 < m->width) {
+ uint16_t t = line[x + n + 1].c;
+ if ((t & 0xfc00) == 0xdc00) {
+ d = t;
+ unicode = (((c & 0x03c0) + 0x0040) << 10) | ((c & 0x003f) << 10) | (d & 0x03ff);
+ } else {
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+ int cw = charWidth(unicode);
+ if (cw < 1) break;
+ if (n == 0) {
+ attr = line[x + n].a;
+ } else {
+ if (attr != line[x + n].a) {
+ break;
+ }
+ }
+ if (d == 0) {
+ text.push_back(c);
+ } else {
+ text.push_back(c);
+ text.push_back(d);
+ }
+ n += cw;
+ }
+ if (n > 0) {
+ Erase();
+ if (!text.isEmpty()) {
+ SetAttribute(attr);
+ std::string s = text.toStdString();
+ move(y, x);
+ waddnstr(stdscr, s.c_str(), s.size());
+ }
+ x += n;
+ erase_x = x;
+ attr = CharAttr();
+ } else {
+ erase++;
+ x++;
+ }
+ }
+ Erase();
+ line_flags()->at(y) &= ~LineChanged;
+ }
+ }
+}
+
+void CursesOreApplication::updateVisibility(bool ensure_current_line_visible, bool change_col, bool auto_scroll)
+{
+ (void)auto_scroll;
+
+ if (ensure_current_line_visible) {
+ ensureCurrentLineVisible();
+ }
+
+// clearParsedLine();
+ updateCursorPos(true);
+
+ int x = cx()->viewport_org_x + cursorX();
+ int y = cx()->viewport_org_y + cursorY();
+
+ if (change_col) {
+ cx()->current_col_hint = cx()->current_col;
+ }
+
+ if (isPaintingSuppressed()) {
+ return;
+ }
+
+ preparePaintScreen();
+
+ paintScreen();
+
+ move(y, x);
+}
+
+
+
+void CursesOreApplication::print_invert_text(int y, const char *text)
+{
+ attron(A_REVERSE);
+ int n = strlen(text);
+ std::vector<char> buf(m->width + 1);
+ if (n > m->width) n = m->width;
+ memcpy(&buf[0], text, n);
+ while (n < m->width) {
+ buf[n] = ' ';
+ n++;
+ }
+ buf[n] = 0;
+ AbstractCharacterBasedApplication::Option opt;
+ print(0, y, &buf[0], opt);
+}
+
+void CursesOreApplication::print_status_text(const char *text)
+{
+ print_invert_text(m->height - 1, text);
+}
+
+int CursesOreApplication::main2()
+{
+ signal(SIGINT, siginthandler);
+
+ initEditor();
+ cx()->engine = TextEditorEnginePtr(new TextEditorEngine);
+
+ setlocale(LC_ALL, "");
+ initscr();
+ if (0) {
+ start_color();
+ init_pair(1, COLOR_BLACK, COLOR_WHITE);
+ }
+ raw();
+ nonl();
+ cbreak();
+ noecho();
+ idlok(stdscr, false);
+ scrollok(stdscr, false);
+ keypad(stdscr, false);
+ m->width = getmaxx(stdscr);
+ m->height = getmaxy(stdscr);
+
+ makeBuffer();
+ loadExampleFile();
+ updateVisibility(true, true, false);
+
+ std::vector<uint8_t> esc;
+ while (1) {
+ refresh();
+ timeout(-1);
+ int c = wgetch(stdscr);
+ if (c == 0x1b) {
+ timeout(5);
+ while (1) {
+ int d = wgetch(stdscr);
+ if (d == ERR) break;
+ if (esc.empty()) {
+ esc.push_back(c);
+ }
+ esc.push_back(d);
+ }
+ }
+ if (!esc.empty()) {
+ c = 0;
+ if (esc.size() == 3) {
+ int e = (esc[0] << 24) | (esc[1] << 16) | (esc[2] << 8);
+ switch (e) {
+ case EscapeCode::Up:
+ case EscapeCode::Down:
+ case EscapeCode::Right:
+ case EscapeCode::Left:
+ case EscapeCode::Home:
+ case EscapeCode::End:
+ c = e;
+ break;
+ }
+ } else if (esc.size() == 4) {
+ int e = (esc[0] << 24) | (esc[1] << 16) | (esc[2] << 8) | esc[3];
+ switch (e) {
+ case EscapeCode::Insert:
+ case EscapeCode::Delete:
+ case EscapeCode::PageUp:
+ case EscapeCode::PageDown:
+ c = e;
+ break;
+ }
+ }
+ esc.clear();
+ } else {
+ {
+ if (c == 0x7f) {
+ doBackspace();
+ c = 0;
+ } else if (c == 0x0d) {
+ c = '\n';
+ }
+ }
+ }
+ if (c) {
+ write(c, true);
+ }
+ if (state() == State::Exit) {
+ break;
+ }
+ }
+ endwin();
+ return 0;
+}
+
+int main2()
+{
+ CursesOreApplication app;
+ app.main2();
+ return 0;
+}
+
+#else
+
+int main2()
+{
+ return 0;
+}
+
+#endif
diff --git a/extra/TextEditor/src/cmain.h b/extra/TextEditor/src/cmain.h
new file mode 100644
index 0000000..744992c
--- /dev/null
+++ b/extra/TextEditor/src/cmain.h
@@ -0,0 +1,35 @@
+#ifndef CMAIN_H
+#define CMAIN_H
+
+#include "texteditor/AbstractCharacterBasedApplication.h"
+
+class CursesOreApplication : public AbstractCharacterBasedApplication {
+public:
+
+ struct Private;
+ Private *m;
+
+ CursesOreApplication();
+ ~CursesOreApplication();
+
+ void print_invert_text(int y, char const *text);
+
+
+ void print_status_text(char const *text);
+
+ int main2();
+
+protected:
+ int screenWidth() const;
+ int screenHeight() const;
+private:
+ void clearLine(int y);
+ void paintScreen();
+
+protected:
+ void updateVisibility(bool ensure_current_line_visible, bool change_col, bool auto_scroll);
+};
+
+int main2();
+
+#endif // CMAIN_H
diff --git a/extra/TextEditor/src/main.cpp b/extra/TextEditor/src/main.cpp
new file mode 100644
index 0000000..82c735b
--- /dev/null
+++ b/extra/TextEditor/src/main.cpp
@@ -0,0 +1,37 @@
+#include "MainWindow.h"
+#include <QApplication>
+#include <QDebug>
+#include "cmain.h"
+
+QString makeApplicationDataDir();
+
+int main(int argc, char *argv[])
+{
+ bool opt_qt = false;
+
+ int i = 1;
+ while (i < argc) {
+ char const *arg = argv[i];
+ if (*arg == '-') {
+ if (strcmp(arg, "-qt") == 0) {
+ opt_qt = true;
+ }
+ }
+ i++;
+ }
+
+ QApplication a(argc, argv);
+
+ if (opt_qt) {
+ a.setOrganizationName("soramimi.jp");
+ a.setApplicationName("ore");
+
+ MainWindow w;
+ w.show();
+
+ return a.exec();
+ } else {
+ main2();
+ return 0;
+ }
+}

File Metadata

Mime Type
text/x-diff
Expires
Mon, Jun 15, 11:29 PM (2 w, 3 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
69804
Default Alt Text
(17 KB)

Event Timeline