コーヒー飲みながら仕事したい

仕事で使う技術的なことの備忘録とか


Wordpress に引っ越しました!

Redmine に EasyGantt のプラグインを入れようとしたらハマったので備忘録

首題の件ですが、 RedmineEasyGantt というプラグインを入れることにしました。
目的としては、このプラグインを入れることで、ドラッグアンドドロップガントチャートが引けるようになるからです。

ガントチャートの運用で一番の問題点は、メンテナンスだと思っています。例えば予定を変更する際に、わざわざ日付を手入力するのはかなりのストレスです。それによって、結果的にメンテナンスが置き去りにされて、最終的にガントチャート使わなくなるという流れを今まで何回も経験してきたので、それに終止符を打つべく、 EasyGantt の導入を試みました。

しかし、このプラグイン導入がなかなかてこずりました。
その備忘録を残しておきます。

前提

環境

  • Redmine は Docker で運用している
  • Redmine のバージョン: 3.4.5 1
  • 使用しているDB: mysql
    • mysql のバージョン: 5.7.21 2
  • Docker が動作しているOS: Windows 10 Pro (Docker For Windows で運用)
  • docker-compose を使用している

概要

先にハマったポイントを列挙しておきます。

手順

結果的に、成功した手順を載せます。

EasyGantt のプラグインを公式からダウンロードする

以下から無料版をダウンロードしました。

www.easyredmine.jp

ダウンロードしたら 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 で確認

f:id:tassi-yuzukko:20190610142252p:plain

上記のように 「Easy Gantt」と表示されていれば、とりあえずプラグインのインストール自体は成功みたいです。


  1. Redmine Ver4.x 以上の場合、 EasyGantt は非対応かもしれないという情報がありました。

  2. mysql v8 以上は認証方式が変更になっているらしく、最初 mysql をバージョンアップしようとしてハマりました。

MQL5 を Visual Studio Code でコンパイルする その2 ~お手軽?コンパイル編~

前回に引き続き、今度はコンパイルできるようにします。

結論から言うと、コンパイルをするだけなら、ググったら既に Qiita 記事で情報公開してくださっている方がいました。
そういったわけで、今回はそちらの記事をほぼ流用する形になりますが、個人的な備忘録として残しておきます。

なお、後述しますがもうちょっとコンパイルを効率良く出来る方法があるみたいなので、次回はそちらにトライします。

参考にさせて頂いた記事は以下です。

qiita.com

概要

まず、どうやってコンパイルするのかという仕組みを備忘録しておきます。

Visual Studio Code では、コンパイル等のユーザー定義処理を tasks.json というものに記載することができるらしいです。
で、どういう仕組みかはわかっていないですが、 ショートカットキーと上記ファイルで定義したタスクが内部でバインディングされているらしく、Ctrl + Shift + B を押すとタスク(つまりコンパイル)が実行されるようです。

tasks.json の用意

適当に ~.mq5 ファイルを開いて、 Ctrl + Shift + B を押すと、以下のようにコマンドパレットのようなものが出てきます。
f:id:tassi-yuzukko:20190526160049p:plain

ここで、 実行するビルドタスクがありません。ビルドタスクを構成する… というところをクリックします。
すると、テンプレートから tasks.json を作成 という表示がでますので、またこれをクリックします。
するとさらに下のような表示になりますので、 Others をクリックします。
f:id:tassi-yuzukko:20190526160433p:plain

すると、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 でも問題なく動作しました。

f:id:tassi-yuzukko:20190525233326p:plain

スニペットやインテリセンスを有効にする

MQL Extension Pack という拡張をインストールすれば良いみたいです。
これをインストールすると、MQL-syntax-over-cppMQL Snippets もいっしょにインストールされます。

f:id:tassi-yuzukko:20190525233521p:plain

インストール後に設定が必要です。

MQL-syntax-over-cpp の設定

README に書いてますが、設定をいじる必要があります。

[Ctrl + Shift + P] と打ち、コマンドパレットを出します。そして、 setting json と入力して、JSON ファイルを表示します。
f:id:tassi-yuzukko:20190525235254p:plain

下記のように README にかかれているので、そのとおり記入します。
f:id:tassi-yuzukko:20190525235352p:plain

f:id:tassi-yuzukko:20190525235409p:plain

留意点として、

"C_Cpp.errorSquiggles": "Disabled"

と記載すると、不要なエラー赤波線を非表示に出来るようです。(非表示にする必要ある?あったほうが良い気もしますね・・・)

デフォルトのインクルード先を登録する

[Ctrl + Shift + P] と打ち、コマンドパレットを出します。そして、 config と入力して、下図のように C/C++:Edit configurations (JSON) を選択します。
f:id:tassi-yuzukko:20190526000547p:plain

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 を使用する場合の仕様のようです。

github.com

ということで、強引に無効にする方法として、以下のようにしました。

using (var context = CreateDbContext(options))
{
    // ↓ これ!!
    context.Database.ExecuteSqlCommand("PRAGMA FOREIGN_KEYS=OFF");

    // 疑似的にメモリ上にDBを生成する
    context.Database.EnsureCreated();

    // 何かしらのテスト処理
    ...
}

PRAGMA という名前からして本当はよろしくない感が半端ないですが、とりあえずこれで外部キー制約を無効にすることが出来ました・・・

EMQ X のインストール

以前、EMQ をインストールしましたが、新しい環境で再度インストールする必要がありました。

tassi-yuzukko.hatenablog.com

詳細はわかりませんが、過去の URL は接続できなくなっていました。
どうやら、「EMQ X」という名前に変わった?みたいなので、再度インストール手順を備忘録として残しておきます。

ダウンロード

こちらからダウンロードします。
サイトのデザインが相変わらずかっこいいです。

www.emqx.io

なお、ドキュメントは以下にあります。

developer.emqx.io

インストール

今回は、 Windows10 64bit 環境でインストールします。

ドキュメントは こちら です。

ダウンロードした zip ファイルを展開し、今回は C:\emqx に展開したファイルを配置しました。

起動

C:\emqx フォルダにて、以下を実行します。

bin\emqx console

ちょっと時間がかかりますが、以下のようなウィンドウが表示されると、起動完了のようです。
何も事前準備が必要ないので、かなり楽チンですね。

f:id:tassi-yuzukko:20190315163341p:plain
emqx

ブラウジング

EMQ の素晴らしいのが、web ブラウザで状態を監視できることです。

http://localhost:18083

↑にアクセスすると、以下のように状態監視できます。

f:id:tassi-yuzukko:20190315163928p:plain

WPF 閉じるボタンのみを非表示にしたウィンドウの作り方

諸事情で閉じるボタン(いわゆる×ボタン)を非表示にしつつ、最小化ボタンのみを残す必要がありました。

たったこれだけのことなのに、結構複雑な処理を実装しないといけなかったので、備忘録として残しておきます。

参考サイト

今回、予想以上に処理が複雑であったため、基本的に参考サイト様のものを組み合わせる形で実現しました。

なので、まず参考サイトを載せておきます。

kuwayoshi.com

social.msdn.microsoft.com

blog.xin9le.net

できあがったもの

もうソースで語らせていただきます。

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 で上下左右(水平垂直方向)に中央寄せするラベルの作り方でハマったので備忘録です。
調べてもなかなかでてこなかった・・

やりたいこと

ずばり、以下の絵のようなやつです。

f:id:tassi-yuzukko:20190304092323p:plain

解決策

以下の自動翻訳されたページに答えがありました。

codeday.me

上記絵のようにするには、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 は自由度高いと言いつつ、規定のコントロールごとに出来ること出来ないことに差がありすぎてツライです・・・
そういうことしたい人はカスタムコントロール作ればいいじゃんって話なのかもしれませんが。(私はコスト高いから嫌だよねーって思っちゃいます)