Page Menu
Home
Phabricator (Chris)
Search
Configure Global Search
Log In
Files
F130440
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
17 KB
Referenced Files
None
Subscribers
None
View Options
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>&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>&Open...</string>
+ </property>
+ </action>
+ <action name="action_file_save">
+ <property name="text">
+ <string>&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
Details
Attached
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)
Attached To
Mode
R77 Guitar
Attached
Detach File
Event Timeline