diff --git a/src/apps/sudoku/SudokuView.cpp b/src/apps/sudoku/SudokuView.cpp index 04be0bcfbf..55dfc819bc 100644 --- a/src/apps/sudoku/SudokuView.cpp +++ b/src/apps/sudoku/SudokuView.cpp @@ -16,10 +16,13 @@ #include #include +#include +#include #include #include #include #include +#include #include @@ -222,128 +225,154 @@ SudokuView::SaveTo(BDataIO &stream, uint32 as) nodeInfo.SetTo(file); switch (as) { - case kExportAsText: - text = "# Written by Sudoku\n\n"; - stream.Write(text.String(), text.Length()); + case kExportAsText: + text = "# Written by Sudoku\n\n"; + stream.Write(text.String(), text.Length()); - line = text.LockBuffer(1024); - memset(line, 0, 1024); - for (uint32 y = 0; y < fField->Size(); y++) { - for (uint32 x = 0; x < fField->Size(); x++) { - if (x != 0 && x % fBlockSize == 0) - line[i++] = ' '; - _SetText(&line[i++], fField->ValueAt(x, y)); + line = text.LockBuffer(1024); + memset(line, 0, 1024); + for (uint32 y = 0; y < fField->Size(); y++) { + for (uint32 x = 0; x < fField->Size(); x++) { + if (x != 0 && x % fBlockSize == 0) + line[i++] = ' '; + _SetText(&line[i++], fField->ValueAt(x, y)); + } + line[i++] = '\n'; } - line[i++] = '\n'; - } - text.UnlockBuffer(); + text.UnlockBuffer(); - stream.Write(text.String(), text.Length()); - if (file) - nodeInfo.SetType("text/plain"); - return B_OK; - case kExportAsHTML: - { - bool netPositiveFriendly = false; - text = "\n\n\n" - "\n" - "\n\n\n"; - /*if (file)*/ - stream.Write(text.String(), text.Length()); + "td.sudoku_nn { border-right: " BS_N "; border-bottom: " BS_N "; }\n" + "td.sudoku_sn { border-right: " BS_S "; border-bottom: " BS_N "; }\n" + "td.sudoku_ns { border-right: " BS_N "; border-bottom: " BS_S "; }\n" + "td.sudoku_ss { border-right: " BS_S "; border-bottom: " BS_S "; }\n" + "td.sudoku_nl { border-right: " BS_N "; border-bottom: " BS_L "; }\n" + "td.sudoku_sl { border-right: " BS_S "; border-bottom: " BS_L "; }\n" + "td.sudoku_ln { border-right: " BS_L "; border-bottom: " BS_N "; }\n" + "td.sudoku_ls { border-right: " BS_L "; border-bottom: " BS_S "; }\n" + "td.sudoku_ll { border-right: " BS_L "; border-bottom: " BS_L "; }\n" + "\n" + "\n\n\n"; + stream.Write(text.String(), text.Length()); - text = ""; - stream.Write(text.String(), text.Length()); + text << " class=\"sudoku\">"; + stream.Write(text.String(), text.Length()); - //XXX: make border larger on %3 - - text = ""; - BString divider; - divider << (int)(100.0 / fField->Size()) << "%"; - for (uint32 y = 0; y < fField->Size(); y++) { - text << "\n"; - for (uint32 x = 0; x < fField->Size(); x++) { - char buff[2]; - _SetText(buff, fField->ValueAt(x, y)); - - char border_right = 's'; - char border_bottom = 's'; - if ((x+1) % fField->BlockSize() == 0) - border_right = 'l'; - if ((y+1) % fField->BlockSize() == 0) - border_bottom = 'l'; - if (x == fField->Size() - 1) - border_right = 'n'; - if (y == fField->Size() - 1) - border_bottom = 'n'; - - if (fField->ValueAt(x, y) == 0) { - text << "\n"; - text << " "; - } else if (fField->FlagsAt(x, y) & kInitialValue) { - text << "\n"; - if (netPositiveFriendly) - text << ""; - text << buff; - if (netPositiveFriendly) - text << ""; - } else { - text << "\n"; - if (netPositiveFriendly) - text << ""; - text << buff; - if (netPositiveFriendly) - text << ""; + text = ""; + BString divider; + divider << (int)(100.0 / fField->Size()) << "%"; + for (uint32 y = 0; y < fField->Size(); y++) { + text << "\n"; + for (uint32 x = 0; x < fField->Size(); x++) { + char buff[2]; + _SetText(buff, fField->ValueAt(x, y)); + + char border_right = 's'; + char border_bottom = 's'; + if ((x+1) % fField->BlockSize() == 0) + border_right = 'l'; + if ((y+1) % fField->BlockSize() == 0) + border_bottom = 'l'; + if (x == fField->Size() - 1) + border_right = 'n'; + if (y == fField->Size() - 1) + border_bottom = 'n'; + + if (fField->ValueAt(x, y) == 0) { + text << "\n"; + text << " "; + } else if (fField->FlagsAt(x, y) & kInitialValue) { + text << "\n"; + if (netPositiveFriendly) + text << ""; + text << buff; + if (netPositiveFriendly) + text << ""; + } else { + text << "\n"; + if (netPositiveFriendly) + text << ""; + text << buff; + if (netPositiveFriendly) + text << ""; + } + text << "\n"; } - text << "\n"; + text << "\n"; } - text << "\n"; - } - text << "\n\n"; + text << "\n\n"; - stream.Write(text.String(), text.Length()); - text = "\n"; - /*if (file)*/ - stream.Write(text.String(), text.Length()); - if (file) - nodeInfo.SetType("text/html"); - return B_OK; - } - case kExportAsBitmap: - case kExportAsPicture: - default: - return EINVAL; + stream.Write(text.String(), text.Length()); + text = "\n"; + stream.Write(text.String(), text.Length()); + if (file) + nodeInfo.SetType("text/html"); + return B_OK; + } + case kExportAsBitmap: + { + BMallocIO mio; + status = SaveTo(mio, kExportAsPicture); + if (status < B_OK) + return status; + mio.Seek(0LL, SEEK_SET); + BPicture picture; + status = picture.Unflatten(&mio); + if (status < B_OK) + return status; + BBitmap *bitmap = new BBitmap(Bounds(), B_BITMAP_ACCEPTS_VIEWS, B_RGB32); + BView *view = new BView(Bounds(), "bitmap", B_FOLLOW_NONE, B_WILL_DRAW); + bitmap->AddChild(view); + if (bitmap->Lock()) { + view->DrawPicture(&picture); + view->Sync(); + view->RemoveSelf(); + delete view; + bitmap->Unlock(); + } + BMessage msg(B_OK); + status = bitmap->Archive(&msg); + if (status >= B_OK) { + status = msg.Flatten(&stream); + } + delete bitmap; + return status; + } + case kExportAsPicture: + { + BPicture picture; + BeginPicture(&picture); + Draw(Bounds()); + if (EndPicture()) { + status = picture.Flatten(&stream); + } + return status; + } + default: + return EINVAL; } return status; @@ -354,7 +383,49 @@ status_t SudokuView::CopyToClipboard() { status_t status = EINVAL; - BMessage data; + BMessage *clip; + if (be_clipboard->Lock()) { + BMallocIO mio; + be_clipboard->Clear(); + clip = be_clipboard->Data(); + if (clip) { + // first as bitmap as we need to archive to the message + if (SaveTo(mio, kExportAsBitmap) >= B_OK) { + mio.Seek(0LL, SEEK_SET); + // ShowImage wants this... nasty + clip->Unflatten(&mio); + // ArtPaint uses that + clip->AddData("image/bitmap", B_MESSAGE_TYPE, mio.Buffer(), mio.BufferLength()); + // Becasso uses that ? + clip->AddData("image/x-be-bitmap", B_MESSAGE_TYPE, mio.Buffer(), mio.BufferLength()); + // Gobe Productive uses that... + // QuickRes as well, with a rect field. + clip->AddData("image/x-vnd.Be-bitmap", B_MESSAGE_TYPE, mio.Buffer(), mio.BufferLength()); + } + mio.Seek(0LL, SEEK_SET); + mio.SetSize(0LL); + + if (SaveTo(mio, kExportAsHTML) >= B_OK) + clip->AddData("text/html", B_MIME_TYPE, mio.Buffer(), mio.BufferLength()); + mio.Seek(0LL, SEEK_SET); + mio.SetSize(0LL); + + if (SaveTo(mio, kExportAsText) >= B_OK) + clip->AddData("text/plain", B_MIME_TYPE, mio.Buffer(), mio.BufferLength()); + mio.Seek(0LL, SEEK_SET); + mio.SetSize(0LL); + + // flattened BPicture, anyone handles that ? + if (SaveTo(mio, kExportAsPicture) >= B_OK) { + clip->AddData("text/x-vnd.Be-picture", B_MIME_TYPE, mio.Buffer(), mio.BufferLength()); + + } + mio.SetSize(0LL); + + be_clipboard->Commit(); + } + be_clipboard->Unlock(); + } return status; } diff --git a/src/apps/sudoku/SudokuView.h b/src/apps/sudoku/SudokuView.h index 8bae2f5600..ca0dfccc44 100644 --- a/src/apps/sudoku/SudokuView.h +++ b/src/apps/sudoku/SudokuView.h @@ -39,8 +39,8 @@ public: status_t SetTo(const char* data); status_t SetTo(SudokuField* field); - status_t SaveTo(entry_ref& ref, uint32 as=kExportAsText); - status_t SaveTo(BDataIO &to, uint32 as=kExportAsText); + status_t SaveTo(entry_ref& ref, uint32 as = kExportAsText); + status_t SaveTo(BDataIO &to, uint32 as = kExportAsText); status_t CopyToClipboard(); diff --git a/src/apps/sudoku/SudokuWindow.cpp b/src/apps/sudoku/SudokuWindow.cpp index 755fe6bc7f..abcdf08094 100644 --- a/src/apps/sudoku/SudokuWindow.cpp +++ b/src/apps/sudoku/SudokuWindow.cpp @@ -217,6 +217,9 @@ SudokuWindow::SudokuWindow() */ menu->AddItem(subMenu); + menu->AddItem(item = new BMenuItem("Copy", + new BMessage(B_COPY), 'C')); + menu->AddSeparatorItem(); menu->AddItem(item = new BMenuItem("About Sudoku" B_UTF8_ELLIPSIS,