⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scintillagtk.cxx.svn-base

📁 Notepad++ is a generic source code editor (it tries to be anyway) and Notepad replacement written in
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
#endif
}

void ScintillaGTK::NotifyParent(SCNotification scn) {
	scn.nmhdr.hwndFrom = PWidget(wMain);
	scn.nmhdr.idFrom = GetCtrlID();
#if GLIB_MAJOR_VERSION < 2
	gtk_signal_emit(GTK_OBJECT(sci), scintilla_signals[NOTIFY_SIGNAL],
	                GetCtrlID(), &scn);
#else
	g_signal_emit(G_OBJECT(sci), scintilla_signals[NOTIFY_SIGNAL], 0,
	                GetCtrlID(), &scn);
#endif
}

void ScintillaGTK::NotifyKey(int key, int modifiers) {
	SCNotification scn = {0};
	scn.nmhdr.code = SCN_KEY;
	scn.ch = key;
	scn.modifiers = modifiers;

	NotifyParent(scn);
}

void ScintillaGTK::NotifyURIDropped(const char *list) {
	SCNotification scn = {0};
	scn.nmhdr.code = SCN_URIDROPPED;
	scn.text = list;

	NotifyParent(scn);
}

const char *CharacterSetID(int characterSet);

const char *ScintillaGTK::CharacterSetID() const {
	return ::CharacterSetID(vs.styles[STYLE_DEFAULT].characterSet);
}

int ScintillaGTK::KeyDefault(int key, int modifiers) {
	if (!(modifiers & SCI_CTRL) && !(modifiers & SCI_ALT)) {
		if (key < 256) {
			NotifyKey(key, modifiers);
			return 0;
		} else {
			// Pass up to container in case it is an accelerator
			NotifyKey(key, modifiers);
			return 0;
		}
	} else {
		// Pass up to container in case it is an accelerator
		NotifyKey(key, modifiers);
		return 0;
	}
	//Platform::DebugPrintf("SK-key: %d %x %x\n",key, modifiers);
}

void ScintillaGTK::CopyToClipboard(const SelectionText &selectedText) {
#ifndef USE_GTK_CLIPBOARD
	copyText.Copy(selectedText);
	gtk_selection_owner_set(GTK_WIDGET(PWidget(wMain)),
				atomClipboard,
				GDK_CURRENT_TIME);
#else
	GtkClipboard *clipBoard;
	clipBoard = gtk_widget_get_clipboard(GTK_WIDGET(PWidget(wMain)), atomClipboard);
	if (clipBoard == NULL) // Occurs if widget isn't in a toplevel
		return;

	SelectionText *clipText = new SelectionText();
	clipText->Copy(selectedText);

	gtk_clipboard_set_with_data(clipBoard, clipboardTargets, nClipboardTargets,
				    ClipboardGetSelection, ClipboardClearSelection, clipText);

#endif
}

void ScintillaGTK::Copy() {
	if (currentPos != anchor) {
#ifndef USE_GTK_CLIPBOARD
		CopySelectionRange(&copyText);
		gtk_selection_owner_set(GTK_WIDGET(PWidget(wMain)),
		                        atomClipboard,
		                        GDK_CURRENT_TIME);
#else
		GtkClipboard *clipBoard;
		clipBoard = gtk_widget_get_clipboard(GTK_WIDGET(PWidget(wMain)), atomClipboard);
		if (clipBoard == NULL) // Occurs if widget isn't in a toplevel
			return;

		SelectionText *clipText = new SelectionText();
		CopySelectionRange(clipText);

		gtk_clipboard_set_with_data(clipBoard, clipboardTargets, nClipboardTargets,
					    ClipboardGetSelection, ClipboardClearSelection, clipText);

#endif
#if PLAT_GTK_WIN32
		if (selType == selRectangle) {
			::OpenClipboard(NULL);
			::SetClipboardData(cfColumnSelect, 0);
			::CloseClipboard();
		}
#endif
	}
}

void ScintillaGTK::Paste() {
	atomSought = atomUTF8;
	gtk_selection_convert(GTK_WIDGET(PWidget(wMain)),
	                      atomClipboard, atomSought, GDK_CURRENT_TIME);
}

void ScintillaGTK::CreateCallTipWindow(PRectangle rc) {
	if (!ct.wCallTip.Created()) {
		ct.wCallTip = gtk_window_new(GTK_WINDOW_POPUP);
		ct.wDraw = gtk_drawing_area_new();
		GtkWidget *widcdrw = PWidget(ct.wDraw);	//	// No code inside the G_OBJECT macro
		gtk_container_add(GTK_CONTAINER(PWidget(ct.wCallTip)), widcdrw);
#if GLIB_MAJOR_VERSION < 2
		gtk_signal_connect(GTK_OBJECT(widcdrw), "expose_event",
				   GtkSignalFunc(ScintillaGTK::ExposeCT), &ct);
		gtk_signal_connect(GTK_OBJECT(widcdrw), "button_press_event",
				   GtkSignalFunc(ScintillaGTK::PressCT), static_cast<void *>(this));
#else
		g_signal_connect(G_OBJECT(widcdrw), "expose_event",
				   G_CALLBACK(ScintillaGTK::ExposeCT), &ct);
		g_signal_connect(G_OBJECT(widcdrw), "button_press_event",
				   G_CALLBACK(ScintillaGTK::PressCT), static_cast<void *>(this));
#endif
		gtk_widget_set_events(widcdrw,
			GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK);
	}
	gtk_drawing_area_size(GTK_DRAWING_AREA(PWidget(ct.wDraw)),
	                      rc.Width(), rc.Height());
	ct.wDraw.Show();
	if (PWidget(ct.wCallTip)->window) {
		gdk_window_resize(PWidget(ct.wCallTip)->window, rc.Width(), rc.Height());
	}
}

void ScintillaGTK::AddToPopUp(const char *label, int cmd, bool enabled) {
	char fulllabel[200];
	strcpy(fulllabel, "/");
	strcat(fulllabel, label);
	GtkItemFactoryCallback menuSig = GtkItemFactoryCallback(PopUpCB);
	GtkItemFactoryEntry itemEntry = {
	    fulllabel, NULL,
	    menuSig,
	    cmd,
	    const_cast<gchar *>(label[0] ? "<Item>" : "<Separator>"),
#if GTK_MAJOR_VERSION >= 2
	    NULL
#endif
	};
	gtk_item_factory_create_item(GTK_ITEM_FACTORY(popup.GetID()),
	                             &itemEntry, this, 1);
	if (cmd) {
		GtkWidget *item = gtk_item_factory_get_widget_by_action(
		                      reinterpret_cast<GtkItemFactory *>(popup.GetID()), cmd);
		if (item)
			gtk_widget_set_sensitive(item, enabled);
	}
}

bool ScintillaGTK::OwnPrimarySelection() {
	return ((gdk_selection_owner_get(GDK_SELECTION_PRIMARY)
		== GTK_WIDGET(PWidget(wMain))->window) &&
			(GTK_WIDGET(PWidget(wMain))->window != NULL));
}

void ScintillaGTK::ClaimSelection() {
	// X Windows has a 'primary selection' as well as the clipboard.
	// Whenever the user selects some text, we become the primary selection
	if (currentPos != anchor && GTK_WIDGET_REALIZED(GTK_WIDGET(PWidget(wMain)))) {
		primarySelection = true;
		gtk_selection_owner_set(GTK_WIDGET(PWidget(wMain)),
		                        GDK_SELECTION_PRIMARY, GDK_CURRENT_TIME);
		primary.Free();
	} else if (OwnPrimarySelection()) {
		primarySelection = true;
		if (primary.s == NULL)
			gtk_selection_owner_set(NULL, GDK_SELECTION_PRIMARY, GDK_CURRENT_TIME);
	} else {
		primarySelection = false;
		primary.Free();
	}
}

// Detect rectangular text, convert line ends to current mode, convert from or to UTF-8
void ScintillaGTK::GetGtkSelectionText(GtkSelectionData *selectionData, SelectionText &selText) {
	char *data = reinterpret_cast<char *>(selectionData->data);
	int len = selectionData->length;
	GdkAtom selectionType = selectionData->type;

	// Return empty string if selection is not a string
	if ((selectionType != GDK_TARGET_STRING) && (selectionType != atomUTF8)) {
		char *empty = new char[1];
		empty[0] = '\0';
		selText.Set(empty, 0, SC_CP_UTF8, 0, false);
		return;
	}

	// Check for "\n\0" ending to string indicating that selection is rectangular
	bool isRectangular;
#if PLAT_GTK_WIN32
	isRectangular = ::IsClipboardFormatAvailable(cfColumnSelect) != 0;
#else
	isRectangular = ((len > 2) && (data[len - 1] == 0 && data[len - 2] == '\n'));
#endif

	char *dest;
	if (selectionType == GDK_TARGET_STRING) {
		dest = Document::TransformLineEnds(&len, data, len, pdoc->eolMode);
		if (IsUnicodeMode()) {
			// Unknown encoding so assume in Latin1
			char *destPrevious = dest;
			dest = UTF8FromLatin1(dest, len);
			selText.Set(dest, len, SC_CP_UTF8, 0, selText.rectangular);
			delete []destPrevious;
		} else {
			// Assume buffer is in same encoding as selection
			selText.Set(dest, len, pdoc->dbcsCodePage,
				vs.styles[STYLE_DEFAULT].characterSet, isRectangular);
		}
	} else {	// UTF-8
		dest = Document::TransformLineEnds(&len, data, len, pdoc->eolMode);
		selText.Set(dest, len, SC_CP_UTF8, 0, isRectangular);
#ifdef USE_CONVERTER
		const char *charSetBuffer = CharacterSetID();
		if (!IsUnicodeMode() && *charSetBuffer) {
//fprintf(stderr, "Convert to locale %s\n", CharacterSetID());
				// Convert to locale
				dest = ConvertText(&len, selText.s, selText.len, charSetBuffer, "UTF-8", true);
				selText.Set(dest, len, pdoc->dbcsCodePage,
					vs.styles[STYLE_DEFAULT].characterSet, selText.rectangular);
		}
#endif
	}
}

void ScintillaGTK::ReceivedSelection(GtkSelectionData *selection_data) {
	if ((selection_data->selection == atomClipboard) ||
		(selection_data->selection == GDK_SELECTION_PRIMARY)) {
		if ((atomSought == atomUTF8) && (selection_data->length <= 0)) {
			atomSought = atomString;
			gtk_selection_convert(GTK_WIDGET(PWidget(wMain)),
					      selection_data->selection, atomSought, GDK_CURRENT_TIME);
		} else if ((selection_data->length > 0) &&
			((selection_data->type == GDK_TARGET_STRING) || (selection_data->type == atomUTF8))) {
			SelectionText selText;
			GetGtkSelectionText(selection_data, selText);

			pdoc->BeginUndoAction();
			if (selection_data->selection != GDK_SELECTION_PRIMARY) {
				ClearSelection();
			}
			int selStart = SelectionStart();

			if (selText.rectangular) {
				PasteRectangular(selStart, selText.s, selText.len);
			} else {
				pdoc->InsertString(currentPos, selText.s, selText.len);
				SetEmptySelection(currentPos + selText.len);
			}
			pdoc->EndUndoAction();
			EnsureCaretVisible();
		}
	}
//	else fprintf(stderr, "Target non string %d %d\n", (int)(selection_data->type),
//		(int)(atomUTF8));
	Redraw();
}

void ScintillaGTK::ReceivedDrop(GtkSelectionData *selection_data) {
	dragWasDropped = true;
	if (selection_data->type == atomUriList || selection_data->type == atomDROPFILES_DND) {
		char *ptr = new char[selection_data->length + 1];
		ptr[selection_data->length] = '\0';
		memcpy(ptr, selection_data->data, selection_data->length);
 		NotifyURIDropped(ptr);
		delete []ptr;
	} else if ((selection_data->type == GDK_TARGET_STRING) || (selection_data->type == atomUTF8)) {
		if (selection_data->length > 0) {
			SelectionText selText;
			GetGtkSelectionText(selection_data, selText);
			DropAt(posDrop, selText.s, false, selText.rectangular);
		}
	} else if (selection_data->length > 0) {
	    //~ fprintf(stderr, "ReceivedDrop other %p\n", static_cast<void *>(selection_data->type));
	}
	Redraw();
}



void ScintillaGTK::GetSelection(GtkSelectionData *selection_data, guint info, SelectionText *text) {
#if PLAT_GTK_WIN32
	// Many native win32 programs require \n line endings, so make a copy of
	// the clip text now with newlines converted.  Use { } to hide symbols
	// from code below
	SelectionText *newline_normalized = NULL;
	{
		int tmpstr_len;
		char *tmpstr = Document::TransformLineEnds(&tmpstr_len, text->s, text->len, SC_EOL_LF);
		newline_normalized = new SelectionText();
		newline_normalized->Set(tmpstr, tmpstr_len, SC_CP_UTF8, 0, text->rectangular);
		text = newline_normalized;
	}
#endif

#if GTK_MAJOR_VERSION >= 2
	// Convert text to utf8 if it isn't already
	SelectionText *converted = 0;
	if ((text->codePage != SC_CP_UTF8) && (info == TARGET_UTF8_STRING)) {
		const char *charSet = ::CharacterSetID(text->characterSet);
		if (*charSet) {
			int new_len;
			char* tmputf = ConvertText(&new_len, text->s, text->len, "UTF-8", charSet, false);
			converted = new SelectionText();
			converted->Set(tmputf, new_len, SC_CP_UTF8, 0, text->rectangular);
			text = converted;
		}
	}

	// Here is a somewhat evil kludge.
	// As I can not work out how to store data on the clipboard in multiple formats
	// and need some way to mark the clipping as being stream or rectangular,
	// the terminating \0 is included in the length for rectangular clippings.
	// All other tested aplications behave benignly by ignoring the \0.
	// The #if is here because on Windows cfColumnSelect clip entry is used
	// instead as standard indicator of rectangularness (so no need to kludge)
	int len = strlen(text->s);
#if PLAT_GTK_WIN32 == 0
	if (text->rectangular)
		len++;
#endif

	if (info == TARGET_UTF8_STRING) {
		gtk_selection_data_set_text(selection_data, text->s, len);
	} else {
		gtk_selection_data_set(selection_data,
			static_cast<GdkAtom>(GDK_SELECTION_TYPE_STRING),
			8, reinterpret_cast<unsigned char *>(text->s), len);
	}
	delete converted;

#else /* Gtk 1 */
	char *selBuffer = text->s;

	char *tmputf = 0;
	if ((info == TARGET_UTF8_STRING) || (info == TARGET_STRING)) {
		int len = strlen(selBuffer);
#ifdef USE_CONVERTER
		// Possible character set conversion
		const char *charSetBuffer = ::CharacterSetID(text->characterSet);
		if (info == TARGET_UTF8_STRING) {
			//fprintf(stderr, "Copy to clipboard as UTF-8\n");
			if (text->codePage != SC_CP_UTF8) {
				// Convert to UTF-8
	//fprintf(stderr, "Convert to UTF-8 from %s\n", charSetBuffer);
				tmputf = ConvertText(&len, selBuffer, len, "UTF-8", charSetBuffer, false);
				selBuffer = tmputf;
			}
		} else if (info == TARGET_STRING) {
			if (text->codePage == SC_CP_UTF8) {
	//fprintf(stderr, "Convert to locale %s\n", charSetBuffer);
				// Convert to locale
				tmputf = ConvertText(&len, selBuffer, len, charSetBuffer, "UTF-8", true);
				selBuffer = tmputf;
			}
		}
#endif

		// Here is a somewhat evil kludge.
		// As I can not work out how to store data on the clipboard in multiple formats
		// and need some way to mark the clipping as being stream or rectangular,
		// the terminating \0 is included in the length for rectangular clippings.
		// All other tested aplications behave benignly by ignoring the \0.
		// The #if is here because on Windows cfColumnSelect clip entry is used
                // instead as standard indicator of rectangularness (so no need to kludge)
#if PLAT_GTK_WIN32 == 0
		if (text->rectangular)
			len++;
#endif
		gtk_selection_data_set(selection_data,
					(info == TARGET_STRING) ?
					static_cast<GdkAtom>(GDK_SELECTION_TYPE_STRING) : atomUTF8,
		                       8, reinterpret_cast<unsigned char *>(selBuffer),
		                       len);
	} else if ((info == TARGET_TEXT) || (info == TARGET_COMPOUND_TEXT)) {
		guchar *text;
		GdkAtom encoding;
		gint format;
		gint new_length;

		gdk_string_to_compound_text(reinterpret_cast<char *>(selBuffer),
		                            &encoding, &format, &text, &new_length);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -