Lesson 6:テキスト編集をしてみる


 ご無沙汰いたしました。毎週更新を目指していたにもかかわらず、一ヶ月も間があいてしまいました。
 それもこれも仕事が忙しいのが悪いんだ。・・・と、その辺の事情は1/7の戯言に書いてあるんで、ここではこの辺で切り上げて・・・。久しぶりにプログラムにいってみましょう。

 今回はテキスト(文字列)の入力と編集(コピー、カット、ペースト、アンドゥ)をやってみます。

 Lesson 3ではテキストの入力に「BTextControl」を使用しました。今回は複数行の入力を行うために、「BTextView」を使用します。BeBookでBTextViewを見れば、BTextControlとBTextViewの関係もわかると思います。

 いつものようにBaseAppを雛型にプロジェクトを作成します(名前はBe4thApp.projとしておきましょうか。)。忘れないうちに、APPLICATION_SIGNATUREやWINDOW_TITLEなどを書き換えておきましょう。
 とりあえずは、BTextViewを表示してみましょう。BAppMainViewのコンストラクタを次のように書き換えます。

/**** ファイル名 : MainWindow.cpp ****/

BAppMainView::BAppMainView(BRect frame)
    :BView(frame,"bappmainview",B_FOLLOW_ALL,B_WILL_DRAW)
{
    BRect viewrect(Bounds());
    textview=new BTextView(viewrect,"textview",
                            BRect(0,0,viewrect.Width(),viewrect.Height()),
                            B_FOLLOW_ALL,B_WILL_DRAW);
    AddChild(textview);
}

 BTextViewのコンストラクタの引数に、BRectを二箇所設定している点に注意してください。
 この状態で実行すると、ウィンドウ全体がテキスト入力欄になります。キーボードから適当に入力してみてください。普通に入力できるはずです。
 ただ、このままですと、スクロールバーが表示されません。そこで、前回同様にBScrollViewを利用します。

/**** ファイル名 : MainWindow.cpp ****/

BAppMainView::BAppMainView(BRect frame)
    :BView(frame,"bappmainview",B_FOLLOW_ALL,B_WILL_DRAW)
{
BAppMainView::BAppMainView(BRect frame)
    :BView(frame,"bappmainview",B_FOLLOW_ALL,B_WILL_DRAW)
{
    BRect viewrect(Bounds());
    BRect f(8,8,viewrect.right-8-B_V_SCROLL_BAR_WIDTH,
            viewrect.bottom-40-B_H_SCROLL_BAR_HEIGHT);

    textview=new BTextView(f,"textview",BRect(0,0,f.Width(),f.Height()),
                            B_FOLLOW_ALL,B_WILL_DRAW);
    BScrollView *scr=new BScrollView("memoscroll",textview,
                                     B_FOLLOW_ALL,0,false,true);
    AddChild(scr);
}

 今度は垂直スクロールバーがつきました。(次の作業のために、ウィンドウ全体ではなく、適当な余白を作っています。)

 今回はテキストの入力と編集を目標にしていますが、この時点で入力は終わってる(入力できてますよね?)ので、次は、編集をやってみましょう。

 一般的なテキストの編集としては、コピー、カット、ペースト、アンドゥがあります。BTextViewも標準でこれらを使用する事ができるようになっています。
 BeBookでBTextViewを調べてみると、メンバ関数にCopy、Cut、Paste、Undoがあることがわかります(なんてわかりやすい名前なんでしょ。)。当然、この関数を使用すれば良いわけです。
 これらの関数を使用するときに注意する点は、引数に、クリップボードを指定してやる必要がある事です。ですが、BeOSのプログラムでは、標準でbe_clipboard変数が準備されていますので、それを利用するだけでOKです。
 普通はメニューを作ってそれぞれの機能を割り当ててやるんですが、メニューについては次回扱いたいので、今回はそれぞれの機能をボタンを作って使用しましょう。今更ボタンの作り方や使い方を説明する必要も無いでしょうから、コードだけを書いておきます。

/**** ファイル名 : MainWindow.h ****/

//---------------------------------------------------------------------
#define MSG_COPY  'cpyb'
#define MSG_CUT   'cutb'
#define MSG_PASTE 'pstb'
#define MSG_UNDO  'udob'
//---------------------------------------------------------------------

/**** ファイル名 : MainWindow.cpp ****/

//---------------------------------------------------------------------
void BAppMainWindow::MessageReceived(BMessage *msg)
{
    switch(msg->what)
    {
        case MSG_COPY:
            mainview->textview->Copy(be_clipboard);
            break;
        case MSG_CUT:
            mainview->textview->Cut(be_clipboard);
            break;
        case MSG_PASTE:
            mainview->textview->Paste(be_clipboard);
            break;
        case MSG_UNDO:
            mainview->textview->Undo(be_clipboard);
            break;
        default:
            BWindow::MessageReceived(msg);
    }
}
//---------------------------------------------------------------------
BAppMainView::BAppMainView(BRect frame)
    :BView(frame,"bappmainview",B_FOLLOW_ALL,B_WILL_DRAW)
{
    BRect viewrect(Bounds());
    BButton *btn;
    BMessage *cpymsg=new BMessage(MSG_COPY);
    BMessage *cutmsg=new BMessage(MSG_CUT);
    BMessage *pstmsg=new BMessage(MSG_PASTE);
    BMessage *udomsg=new BMessage(MSG_UNDO);

    BRect f(8,8,viewrect.right-8-B_V_SCROLL_BAR_WIDTH,
            viewrect.bottom-40-B_H_SCROLL_BAR_HEIGHT);

    textview=new BTextView(f,"textview",BRect(0,0,f.Width(),f.Height()),
                            B_FOLLOW_ALL,B_WILL_DRAW);
    BScrollView *scr=new BScrollView("memoscroll",textview,
                                     B_FOLLOW_ALL,0,false,true);
    AddChild(scr);

    btn=new BButton(BRect(viewrect.right-68,viewrect.bottom-32,
                          viewrect.right-8,viewrect.bottom-8),
                    "undobtn","UNDO",udomsg);
    AddChild(btn);

    btn=new BButton(BRect(viewrect.right-136,viewrect.bottom-32,
                          viewrect.right-76,viewrect.bottom-8),
                    "pastebtn","PASTE",pstmsg);
    AddChild(btn);

    btn=new BButton(BRect(viewrect.right-204,viewrect.bottom-32,
                          viewrect.right-144,viewrect.bottom-8),
                    "cutbtn","CUT",cutmsg);
    AddChild(btn);

    btn=new BButton(BRect(viewrect.right-272,viewrect.bottom-32,
                          viewrect.right-212,viewrect.bottom-8),
                    "copybtn","COPY",cpymsg);
    AddChild(btn);
}
//---------------------------------------------------------------------

 プログラムを動かしてみてください。コピー、カット、ペーストが正しく使えていますよね。でも実は、アンドゥは動かないです。
 そこでまたBeBookで調べてみると・・・、どうもアンドゥの使用は可否の設定ができるようで、その関数は 「SetDoesUndo」のようです。そこでtextviewにSetDoesUndoでアンドゥを使用できるように設定するためBAppMainViewのコンストラクタに
textview->SetDoesUndo(true);
を追加します。
 変更したら動作を確認してみてください。今度はアンドゥができるようになっているはずです。

 今回はこれで終わりです。次回はメニューに挑戦します。

ソースリスト
圧縮ファイル
R5 Intel環境で確認
Be4thApp20000120.zip
ソースファイル
BaseApp.h
main.cpp
MainWindow.cpp
MainWindow.h

次の項目へ

トップページへ戻る