Redmine に EasyGantt のプラグインを入れようとしたらハマったので備忘録
首題の件ですが、 Redmine に EasyGantt というプラグインを入れることにしました。
目的としては、このプラグインを入れることで、ドラッグアンドドロップでガントチャートが引けるようになるからです。
ガントチャートの運用で一番の問題点は、メンテナンスだと思っています。例えば予定を変更する際に、わざわざ日付を手入力するのはかなりのストレスです。それによって、結果的にメンテナンスが置き去りにされて、最終的にガントチャート使わなくなるという流れを今まで何回も経験してきたので、それに終止符を打つべく、 EasyGantt の導入を試みました。
しかし、このプラグイン導入がなかなかてこずりました。
その備忘録を残しておきます。
前提
環境
- Redmine は Docker で運用している
- Redmine のバージョン:
3.4.5
1 - 使用しているDB: mysql
- Docker が動作しているOS: Windows 10 Pro (Docker For Windows で運用)
- docker-compose を使用している
概要
先にハマったポイントを列挙しておきます。
- volume のマウントがうまくいかない
- プラグインの導入方法が、 docker-redmine の公式 に書いてある方法ではうまくいかなかった
手順
結果的に、成功した手順を載せます。
EasyGantt のプラグインを公式からダウンロードする
以下から無料版をダウンロードしました。
ダウンロードしたら EasyGanttFree-3.x.zip
を解凍して、docker-compose.yml の存在するディレクトリに置きます。
docker-compose ファイルを修正する
version: '3.1' services: redmine: image: redmine:3.4.5 container_name: redmine restart: always ports: - 3000:3000 environment: REDMINE_DB_MYSQL: mysql REDMINE_DB_PASSWORD: example http_proxy: XXXXXXXXXXX https_proxy: XXXXXXXXXXXX volumes: - files:/usr/src/redmine/files # ↓これを追加 - easy_gantt:/usr/src/redmine/plugins/easy_gantt networks: - common mysql: image: mysql:5.7 container_name: redmine-mysql command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci restart: always environment: MYSQL_ROOT_PASSWORD: example MYSQL_DATABASE: redmine http_proxy: XXXXXXXXXXXX https_proxy: XXXXXXXXXXXX volumes: - mysql:/var/lib/mysql networks: - common networks: common: external: true volumes: files: mysql: # ↓これを追加 easy_gantt:
Docker で普通に Redmine を起動する
PowerShell を起動して、以下コマンドで Redmine を起動します。
$ docker-compose up --build
以上で完了のはずです。
追記
これだけだと、コンテナ内にプラグインが展開されていないことがあったので、その場合は以下を実行しました。(コンテナの外側から)
$ docker cp .\easy_gantt\ redmine:/usr/src/redmine/plugins
これで、コンテナの外側からプラグインをコンテナ内に配置できます。
Redmine で確認
上記のように 「Easy Gantt」と表示されていれば、とりあえずプラグインのインストール自体は成功みたいです。
MQL5 を Visual Studio Code でコンパイルする その2 ~お手軽?コンパイル編~
結論から言うと、コンパイルをするだけなら、ググったら既に Qiita 記事で情報公開してくださっている方がいました。
そういったわけで、今回はそちらの記事をほぼ流用する形になりますが、個人的な備忘録として残しておきます。
なお、後述しますがもうちょっとコンパイルを効率良く出来る方法があるみたいなので、次回はそちらにトライします。
参考にさせて頂いた記事は以下です。
概要
まず、どうやってコンパイルするのかという仕組みを備忘録しておきます。
Visual Studio Code では、コンパイル等のユーザー定義処理を tasks.json
というものに記載することができるらしいです。
で、どういう仕組みかはわかっていないですが、 ショートカットキーと上記ファイルで定義したタスクが内部でバインディングされているらしく、Ctrl + Shift + B
を押すとタスク(つまりコンパイル)が実行されるようです。
tasks.json の用意
適当に ~.mq5
ファイルを開いて、 Ctrl + Shift + B
を押すと、以下のようにコマンドパレットのようなものが出てきます。
ここで、 実行するビルドタスクがありません。ビルドタスクを構成する…
というところをクリックします。
すると、テンプレートから tasks.json を作成
という表示がでますので、またこれをクリックします。
するとさらに下のような表示になりますので、 Others
をクリックします。
すると、tasks.json
が自動生成されるので、今回はこちらに以下をコピペしました。(参照元: MQL4をVSCode(とMT4)でコンパイルする! - Qiita )
ちなみに、私の環境は Windows10 なので以下の方法はたぶん Windows 系 OS でのみ有効だと思います。
{ "version": "2.0.0", "tasks": [ { "label": "MQL4-Compile", "group": { "kind" : "build", "isDefault" : true }, "presentation": { "echo" : true, "reveal": "always", "focus" : true, "panel" : "shared" }, "promptOnClose" : true, "type" : "process", "command" : "C:\\Program Files\\XMTrading MT5\\metaeditor64.exe", // ← これは MT5 のインストール先により異なる "args" : [ "/compile:${fileBasename}", "/log:${fileBasenameNoExtension}.log", ] } ] }
ビルド
~.mq5
ファイルを開いて、 Ctrl + Shift + B
を押すとビルドが実行されるようになります。
ビルド結果は ~.log
ファイルに記載されます。
私の場合、これでビルドが成功しました。
ちょっと惜しいところ
ビルドログがターミナルに表示されません。
コンパイル完了したのかエラーだったのかは、~.log
ファイルに記載されます。
そういった意味で、 Visual Studio みたいに結果がターミナルに表示され、エラー場所をクリックすると該当箇所にジャンプできる機能を実現する方法が、前回の参考記事であるこちらに載っています。
次回はこっちにチャレンジしてみます。
MQL5 を Visual Studio Code でコンパイルする その1 ~シンタックスハイライト編~
ちょっとこのブログに書くべきか悩みましたが、 MetaTrader5 で使用する MQL5 と呼ばれる言語に関する記事です。
一応プログラム言語に関することなので、書くことにしました。
(MetaTrader5 が何かはここでは述べません)
ちなみに、今回の記事は、こちらの情報を日本語にしただけです。
まずは、シンタックスハイライトまでです。
シンタックスハイライトを有効にする
MQL4 Syntax Highlight
という拡張をインストールすると、シンタックスハイライトが有効になります。
MQL4 となっていますが、 MQL5 でも問題なく動作しました。
スニペットやインテリセンスを有効にする
MQL Extension Pack
という拡張をインストールすれば良いみたいです。
これをインストールすると、MQL-syntax-over-cpp
と MQL Snippets
もいっしょにインストールされます。
インストール後に設定が必要です。
MQL-syntax-over-cpp の設定
README に書いてますが、設定をいじる必要があります。
[Ctrl + Shift + P]
と打ち、コマンドパレットを出します。そして、 setting json
と入力して、JSON ファイルを表示します。
下記のように README にかかれているので、そのとおり記入します。
↓
留意点として、
"C_Cpp.errorSquiggles": "Disabled"
と記載すると、不要なエラー赤波線を非表示に出来るようです。(非表示にする必要ある?あったほうが良い気もしますね・・・)
デフォルトのインクルード先を登録する
[Ctrl + Shift + P]
と打ち、コマンドパレットを出します。そして、 config
と入力して、下図のように C/C++:Edit configurations (JSON)
を選択します。
JSON ファイルが表示されますので、 "includePath"
属性に、以下を追加します。
(※ 環境によって異なると思います)
"C:\\Users\\XXXX\\AppData\\Roaming\\MetaQuotes\\Terminal\\XXXXXXXXXXXXXXXXXXXXXXXXX\\MQL5\\Include"
次回は、実際にコンパイルするところまでを設定しようと思います。
注意
参考記事では、 git と MQL5ストレージが共存できないことを警告しています。
一応気に留めといておいたほうが良いでしょうね。
個人的には git が好きなので、当面はMQL5ストレージは使用しないでおこうと思います。
SQLite を使用して単体テストしていると、'FOREIGN KEY constraint failed' と怒られる
単体テストで SQLite を使用していて困ったことが合ったので、その概要と解決策です。
外部キー制約にひっかかる
DB を使用する箇所の単体テストにおいて SQLite を使用することで簡単にテスト環境を構築することが出来ます。とりあえずテストしたいところだけをピンポイントでメモリ上にデータベースを作ることが出来るので、テスト環境をわざわざ用意する必要もないですし。
しかし、今回テスト実行時、context.SaveChanges()
のタイミングで以下のような例外がでました。
SqliteException: SQLite Error 19: FOREIGN KEY constraint failed
どうやら外部キー制約にひっかかっているみたいです。
しかし、単体テストなのでわざわざ外部キー制約までしっかりしたメモリ上DBを用意するのはは面倒です。(というかそういう面倒なことを排除できることが魅力だし)
どうしたものかと調べてみると、安定の StackOverflow に回答がありましたので残しておきます。
外部キー制約を強制的に無効にする
どうやら SQLite でもデフォルトでは外部キー制約が有効になっているようです。
これを無効にする方法として↓でいろいろ議論されていますが、どうやら EF Core で SQLite を使用する場合の仕様のようです。
ということで、強引に無効にする方法として、以下のようにしました。
using (var context = CreateDbContext(options)) { // ↓ これ!! context.Database.ExecuteSqlCommand("PRAGMA FOREIGN_KEYS=OFF"); // 疑似的にメモリ上にDBを生成する context.Database.EnsureCreated(); // 何かしらのテスト処理 ... }
PRAGMA
という名前からして本当はよろしくない感が半端ないですが、とりあえずこれで外部キー制約を無効にすることが出来ました・・・
EMQ X のインストール
以前、EMQ をインストールしましたが、新しい環境で再度インストールする必要がありました。
詳細はわかりませんが、過去の URL は接続できなくなっていました。
どうやら、「EMQ X」という名前に変わった?みたいなので、再度インストール手順を備忘録として残しておきます。
ダウンロード
こちらからダウンロードします。
サイトのデザインが相変わらずかっこいいです。
なお、ドキュメントは以下にあります。
インストール
今回は、 Windows10 64bit 環境でインストールします。
ドキュメントは こちら です。
ダウンロードした zip ファイルを展開し、今回は C:\emqx
に展開したファイルを配置しました。
起動
C:\emqx
フォルダにて、以下を実行します。
bin\emqx console
ちょっと時間がかかりますが、以下のようなウィンドウが表示されると、起動完了のようです。
何も事前準備が必要ないので、かなり楽チンですね。
ブラウジング
EMQ の素晴らしいのが、web ブラウザで状態を監視できることです。
↑にアクセスすると、以下のように状態監視できます。
WPF 閉じるボタンのみを非表示にしたウィンドウの作り方
諸事情で閉じるボタン(いわゆる×ボタン)を非表示にしつつ、最小化ボタンのみを残す必要がありました。
たったこれだけのことなのに、結構複雑な処理を実装しないといけなかったので、備忘録として残しておきます。
参考サイト
今回、予想以上に処理が複雑であったため、基本的に参考サイト様のものを組み合わせる形で実現しました。
なので、まず参考サイトを載せておきます。
できあがったもの
もうソースで語らせていただきます。
public partial class MainWindow : Window { [DllImport("user32.dll")] private static extern int GetWindowLong(IntPtr hWnd, int nIndex); [DllImport("user32.dll")] private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong); [DllImport("user32.dll")] private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert); [DllImport("user32.dll")] private static extern bool EnableMenuItem(IntPtr hMenu, uint uIDEnableItem, uint uEnable); const int GWL_STYLE = -16; const int WS_MAXIMIZEBOX = 0x10000; const int WS_MINIMIZEBOX = 0x20000; private const uint MF_BYCOMMAND = 0x00000000; private const uint MF_GRAYED = 0x00000001; private const uint MF_ENABLED = 0x00000000; private const uint SC_CLOSE = 0xF060; private const int WM_SHOWWINDOW = 0x00000018; private const int WM_SYSCOMMAND = 0x112; private const int WM_CLOSE = 0x10; private HwndSource hwndSource = null; protected override void OnSourceInitialized(EventArgs e) { base.OnSourceInitialized(e); hwndSource = PresentationSource.FromVisual(this) as HwndSource; if (hwndSource != null) { hwndSource.AddHook(new HwndSourceHook(this.hwndSourceHook)); } var handle = new WindowInteropHelper(this).Handle; int style = GetWindowLong(handle, GWL_STYLE); style = style & (~WS_MAXIMIZEBOX); // 最小化も消したければ WS_MINIMIZEBOX を指定 SetWindowLong(handle, GWL_STYLE, style); } private IntPtr hwndSourceHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { if (msg == WM_SHOWWINDOW) { IntPtr hMenu = GetSystemMenu(hwnd, false); if (hMenu != IntPtr.Zero) { EnableMenuItem(hMenu, SC_CLOSE, MF_BYCOMMAND | MF_GRAYED); } } else if (msg == WM_SYSCOMMAND && (wParam.ToInt32() & 0xFFF0) == SC_CLOSE) { handled = true; } return IntPtr.Zero; } public MainWindow() { InitializeComponent(); } }
WPF で 上下左右に中央寄せのラベル(テキストボックス)を作る
WPF で上下左右(水平垂直方向)に中央寄せするラベルの作り方でハマったので備忘録です。
調べてもなかなかでてこなかった・・
やりたいこと
ずばり、以下の絵のようなやつです。
解決策
以下の自動翻訳されたページに答えがありました。
上記絵のようにするには、XAML を以下のように書きます。
<StackPanel> <Border BorderBrush="Black" Height="200" Margin="30" BorderThickness="1"> <TextBlock Text="Some Text" VerticalAlignment="Center" Width="100" TextAlignment="Center" /> </Border> </StackPanel>
ポイントとしては以下です。
- 一見テキストボックスが大きいように見えるが、実体としては
Border
コントロールが大きくて、Textbox
自体は小さい - Textbox は
VerticalAlignment="Center"
にすることで垂直方向に中央寄せすることはできますが、その場合「高さが1行分」という条件が発生する。もし Textbox 自体の高さを変更すると中央寄せにならない - そのため、Border 自体を大きくして、見た目上 Textbox の高さを大きくしているようにする
ちなみに、上記で Border の境界線が不要ならば、BorderBrush="{x:Null}"
とすることで境界線なしに出来ます。
補足(というか愚痴)
なお、レガシーな GUI アプリを作ってきたものからすると、こういう用途では「Label」を使用するイメージだったのですが、ラベルは「文字を水平方向にセンタライズできない」という謎仕様があるため、こういう用途では使えないっぽいです。
WPF は自由度高いと言いつつ、規定のコントロールごとに出来ること出来ないことに差がありすぎてツライです・・・
そういうことしたい人はカスタムコントロール作ればいいじゃんって話なのかもしれませんが。(私はコスト高いから嫌だよねーって思っちゃいます)