* Reindent & style fix.
* Added copy-to-clipboard. * Added picture and bitmap clipboard formats. Now you can just paste into either a text or graphics app. Even Gobe uses the text in word processor and bitmap in picture editor :) git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23855 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
+182
-111
@@ -16,10 +16,13 @@
|
|||||||
|
|
||||||
#include <Application.h>
|
#include <Application.h>
|
||||||
#include <Beep.h>
|
#include <Beep.h>
|
||||||
|
#include <Bitmap.h>
|
||||||
|
#include <Clipboard.h>
|
||||||
#include <DataIO.h>
|
#include <DataIO.h>
|
||||||
#include <File.h>
|
#include <File.h>
|
||||||
#include <NodeInfo.h>
|
#include <NodeInfo.h>
|
||||||
#include <Path.h>
|
#include <Path.h>
|
||||||
|
#include <Picture.h>
|
||||||
#include <String.h>
|
#include <String.h>
|
||||||
|
|
||||||
|
|
||||||
@@ -222,128 +225,154 @@ SudokuView::SaveTo(BDataIO &stream, uint32 as)
|
|||||||
nodeInfo.SetTo(file);
|
nodeInfo.SetTo(file);
|
||||||
|
|
||||||
switch (as) {
|
switch (as) {
|
||||||
case kExportAsText:
|
case kExportAsText:
|
||||||
text = "# Written by Sudoku\n\n";
|
text = "# Written by Sudoku\n\n";
|
||||||
stream.Write(text.String(), text.Length());
|
stream.Write(text.String(), text.Length());
|
||||||
|
|
||||||
line = text.LockBuffer(1024);
|
line = text.LockBuffer(1024);
|
||||||
memset(line, 0, 1024);
|
memset(line, 0, 1024);
|
||||||
for (uint32 y = 0; y < fField->Size(); y++) {
|
for (uint32 y = 0; y < fField->Size(); y++) {
|
||||||
for (uint32 x = 0; x < fField->Size(); x++) {
|
for (uint32 x = 0; x < fField->Size(); x++) {
|
||||||
if (x != 0 && x % fBlockSize == 0)
|
if (x != 0 && x % fBlockSize == 0)
|
||||||
line[i++] = ' ';
|
line[i++] = ' ';
|
||||||
_SetText(&line[i++], fField->ValueAt(x, y));
|
_SetText(&line[i++], fField->ValueAt(x, y));
|
||||||
|
}
|
||||||
|
line[i++] = '\n';
|
||||||
}
|
}
|
||||||
line[i++] = '\n';
|
text.UnlockBuffer();
|
||||||
}
|
|
||||||
text.UnlockBuffer();
|
|
||||||
|
|
||||||
stream.Write(text.String(), text.Length());
|
stream.Write(text.String(), text.Length());
|
||||||
if (file)
|
if (file)
|
||||||
nodeInfo.SetType("text/plain");
|
nodeInfo.SetType("text/plain");
|
||||||
return B_OK;
|
return B_OK;
|
||||||
case kExportAsHTML:
|
case kExportAsHTML:
|
||||||
{
|
{
|
||||||
bool netPositiveFriendly = false;
|
bool netPositiveFriendly = false;
|
||||||
text = "<html>\n<head>\n<!-- Written by Sudoku -->\n"
|
text = "<html>\n<head>\n<!-- Written by Sudoku -->\n"
|
||||||
"<style type=\"text/css\">\n"
|
"<style type=\"text/css\">\n"
|
||||||
/*
|
"table.sudoku { background: #000000; border:0; border-collapse: collapse; cellpadding: 10px; cellspacing: 10px; width: 300px; height: 300px; }\n"
|
||||||
"table.sudoku { background: #000000; border:0; cellpadding: 10px; cellspacing: 1px; width: 300px; height: 300px; }\n"
|
"td.sudoku { background: #ffffff; border-color: black; border-left: none ; border-top: none ; /*border: none;*/ text-align: center; }\n"
|
||||||
"td.sudoku { background: #ffffff; border: 0; text-align: center; }\n"
|
"td.sudoku_initial { }\n"
|
||||||
"td.sudoku_initial { }\n"
|
"td.sudoku_filled { color: blue; }\n"
|
||||||
"td.sudoku_filled { color: blue; }\n"
|
"td.sudoku_empty { }\n"
|
||||||
"td.sudoku_empty { }\n"
|
// border styles: right bottom (none, solid or large)
|
||||||
*/
|
|
||||||
"table.sudoku { background: #000000; border:0; border-collapse: collapse; cellpadding: 10px; cellspacing: 10px; width: 300px; height: 300px; }\n"
|
|
||||||
"td.sudoku { background: #ffffff; border-color: black; border-left: none ; border-top: none ; /*border: none;*/ text-align: center; }\n"
|
|
||||||
"td.sudoku_initial { }\n"
|
|
||||||
"td.sudoku_filled { color: blue; }\n"
|
|
||||||
"td.sudoku_empty { }\n"
|
|
||||||
// border styles: right bottom (none, solid or large)
|
|
||||||
#define BS_N "none"
|
#define BS_N "none"
|
||||||
#define BS_S "solid 1px black"
|
#define BS_S "solid 1px black"
|
||||||
#define BS_L "solid 3px black"
|
#define BS_L "solid 3px black"
|
||||||
"td.sudoku_nn { border-right: " BS_N "; border-bottom: " BS_N "; }\n"
|
"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_sn { border-right: " BS_S "; border-bottom: " BS_N "; }\n"
|
||||||
"td.sudoku_ns { border-right: " BS_N "; border-bottom: " BS_S "; }\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_ss { border-right: " BS_S "; border-bottom: " BS_S "; }\n"
|
||||||
"td.sudoku_nl { border-right: " BS_N "; border-bottom: " BS_L "; }\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_sl { border-right: " BS_S "; border-bottom: " BS_L "; }\n"
|
||||||
"td.sudoku_ln { border-right: " BS_L "; border-bottom: " BS_N "; }\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_ls { border-right: " BS_L "; border-bottom: " BS_S "; }\n"
|
||||||
"td.sudoku_ll { border-right: " BS_L "; border-bottom: " BS_L "; }\n"
|
"td.sudoku_ll { border-right: " BS_L "; border-bottom: " BS_L "; }\n"
|
||||||
"</style>\n"
|
"</style>\n"
|
||||||
"</head>\n<body>\n\n";
|
"</head>\n<body>\n\n";
|
||||||
/*if (file)*/
|
stream.Write(text.String(), text.Length());
|
||||||
stream.Write(text.String(), text.Length());
|
|
||||||
|
|
||||||
text = "<table";
|
text = "<table";
|
||||||
if (netPositiveFriendly)
|
if (netPositiveFriendly)
|
||||||
text << " border=\"1\"";
|
text << " border=\"1\"";
|
||||||
text << " class=\"sudoku\">";
|
text << " class=\"sudoku\">";
|
||||||
stream.Write(text.String(), text.Length());
|
stream.Write(text.String(), text.Length());
|
||||||
|
|
||||||
//XXX: make border larger on %3
|
text = "";
|
||||||
|
BString divider;
|
||||||
text = "";
|
divider << (int)(100.0 / fField->Size()) << "%";
|
||||||
BString divider;
|
for (uint32 y = 0; y < fField->Size(); y++) {
|
||||||
divider << (int)(100.0 / fField->Size()) << "%";
|
text << "<tr height=\"" << divider << "\">\n";
|
||||||
for (uint32 y = 0; y < fField->Size(); y++) {
|
for (uint32 x = 0; x < fField->Size(); x++) {
|
||||||
text << "<tr height=\"" << divider << "\">\n";
|
char buff[2];
|
||||||
for (uint32 x = 0; x < fField->Size(); x++) {
|
_SetText(buff, fField->ValueAt(x, y));
|
||||||
char buff[2];
|
|
||||||
_SetText(buff, fField->ValueAt(x, y));
|
char border_right = 's';
|
||||||
|
char border_bottom = 's';
|
||||||
char border_right = 's';
|
if ((x+1) % fField->BlockSize() == 0)
|
||||||
char border_bottom = 's';
|
border_right = 'l';
|
||||||
if ((x+1) % fField->BlockSize() == 0)
|
if ((y+1) % fField->BlockSize() == 0)
|
||||||
border_right = 'l';
|
border_bottom = 'l';
|
||||||
if ((y+1) % fField->BlockSize() == 0)
|
if (x == fField->Size() - 1)
|
||||||
border_bottom = 'l';
|
border_right = 'n';
|
||||||
if (x == fField->Size() - 1)
|
if (y == fField->Size() - 1)
|
||||||
border_right = 'n';
|
border_bottom = 'n';
|
||||||
if (y == fField->Size() - 1)
|
|
||||||
border_bottom = 'n';
|
if (fField->ValueAt(x, y) == 0) {
|
||||||
|
text << "<td width=\"" << divider << "\" ";
|
||||||
if (fField->ValueAt(x, y) == 0) {
|
text << "class=\"sudoku sudoku_empty sudoku_" << border_right << border_bottom << "\">\n";
|
||||||
text << "<td width=\"" << divider << "\" ";
|
text << " ";
|
||||||
text << "class=\"sudoku sudoku_empty sudoku_" << border_right << border_bottom << "\">\n";
|
} else if (fField->FlagsAt(x, y) & kInitialValue) {
|
||||||
text << " ";
|
text << "<td width=\"" << divider << "\" ";
|
||||||
} else if (fField->FlagsAt(x, y) & kInitialValue) {
|
text << "class=\"sudoku sudoku_initial sudoku_" << border_right << border_bottom << "\">\n";
|
||||||
text << "<td width=\"" << divider << "\" ";
|
if (netPositiveFriendly)
|
||||||
text << "class=\"sudoku sudoku_initial sudoku_" << border_right << border_bottom << "\">\n";
|
text << "<font color=\"#000000\">";
|
||||||
if (netPositiveFriendly)
|
text << buff;
|
||||||
text << "<font color=\"#000000\">";
|
if (netPositiveFriendly)
|
||||||
text << buff;
|
text << "</font>";
|
||||||
if (netPositiveFriendly)
|
} else {
|
||||||
text << "</font>";
|
text << "<td width=\"" << divider << "\" ";
|
||||||
} else {
|
text << "class=\"sudoku sudoku_filled sudoku_" << border_right << border_bottom << "\">\n";
|
||||||
text << "<td width=\"" << divider << "\" ";
|
if (netPositiveFriendly)
|
||||||
text << "class=\"sudoku sudoku_filled sudoku_" << border_right << border_bottom << "\">\n";
|
text << "<font color=\"#0000ff\">";
|
||||||
if (netPositiveFriendly)
|
text << buff;
|
||||||
text << "<font color=\"#0000ff\">";
|
if (netPositiveFriendly)
|
||||||
text << buff;
|
text << "</font>";
|
||||||
if (netPositiveFriendly)
|
}
|
||||||
text << "</font>";
|
text << "</td>\n";
|
||||||
}
|
}
|
||||||
text << "</td>\n";
|
text << "</tr>\n";
|
||||||
}
|
}
|
||||||
text << "</tr>\n";
|
text << "</table>\n\n";
|
||||||
}
|
|
||||||
text << "</table>\n\n";
|
|
||||||
|
|
||||||
stream.Write(text.String(), text.Length());
|
stream.Write(text.String(), text.Length());
|
||||||
text = "</body></html>\n";
|
text = "</body></html>\n";
|
||||||
/*if (file)*/
|
stream.Write(text.String(), text.Length());
|
||||||
stream.Write(text.String(), text.Length());
|
if (file)
|
||||||
if (file)
|
nodeInfo.SetType("text/html");
|
||||||
nodeInfo.SetType("text/html");
|
return B_OK;
|
||||||
return B_OK;
|
}
|
||||||
}
|
case kExportAsBitmap:
|
||||||
case kExportAsBitmap:
|
{
|
||||||
case kExportAsPicture:
|
BMallocIO mio;
|
||||||
default:
|
status = SaveTo(mio, kExportAsPicture);
|
||||||
return EINVAL;
|
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;
|
return status;
|
||||||
@@ -354,7 +383,49 @@ status_t
|
|||||||
SudokuView::CopyToClipboard()
|
SudokuView::CopyToClipboard()
|
||||||
{
|
{
|
||||||
status_t status = EINVAL;
|
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;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,8 +39,8 @@ public:
|
|||||||
status_t SetTo(const char* data);
|
status_t SetTo(const char* data);
|
||||||
status_t SetTo(SudokuField* field);
|
status_t SetTo(SudokuField* field);
|
||||||
|
|
||||||
status_t SaveTo(entry_ref& ref, uint32 as=kExportAsText);
|
status_t SaveTo(entry_ref& ref, uint32 as = kExportAsText);
|
||||||
status_t SaveTo(BDataIO &to, uint32 as=kExportAsText);
|
status_t SaveTo(BDataIO &to, uint32 as = kExportAsText);
|
||||||
|
|
||||||
status_t CopyToClipboard();
|
status_t CopyToClipboard();
|
||||||
|
|
||||||
|
|||||||
@@ -217,6 +217,9 @@ SudokuWindow::SudokuWindow()
|
|||||||
*/
|
*/
|
||||||
menu->AddItem(subMenu);
|
menu->AddItem(subMenu);
|
||||||
|
|
||||||
|
menu->AddItem(item = new BMenuItem("Copy",
|
||||||
|
new BMessage(B_COPY), 'C'));
|
||||||
|
|
||||||
menu->AddSeparatorItem();
|
menu->AddSeparatorItem();
|
||||||
|
|
||||||
menu->AddItem(item = new BMenuItem("About Sudoku" B_UTF8_ELLIPSIS,
|
menu->AddItem(item = new BMenuItem("About Sudoku" B_UTF8_ELLIPSIS,
|
||||||
|
|||||||
Reference in New Issue
Block a user