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

📄 scintillagtk.cxx

📁 一个可以提供语法高亮显示的编辑器
💻 CXX
📖 第 1 页 / 共 5 页
字号:
	bool modified = false;
	int pageScroll = LinesToScroll();

	if (GTK_ADJUSTMENT(adjustmentv)->upper != (nMax + 1) ||
	        GTK_ADJUSTMENT(adjustmentv)->page_size != nPage ||
	        GTK_ADJUSTMENT(adjustmentv)->page_increment != pageScroll) {
		GTK_ADJUSTMENT(adjustmentv)->upper = nMax + 1;
		GTK_ADJUSTMENT(adjustmentv)->page_size = nPage;
		GTK_ADJUSTMENT(adjustmentv)->page_increment = pageScroll;
		gtk_adjustment_changed(GTK_ADJUSTMENT(adjustmentv));
		modified = true;
	}

	PRectangle rcText = GetTextRectangle();
	int horizEndPreferred = scrollWidth;
	if (horizEndPreferred < 0)
		horizEndPreferred = 0;
	unsigned int pageWidth = rcText.Width();
	if (GTK_ADJUSTMENT(adjustmenth)->upper != horizEndPreferred ||
	        GTK_ADJUSTMENT(adjustmenth)->page_size != pageWidth) {
		GTK_ADJUSTMENT(adjustmenth)->upper = horizEndPreferred;
		GTK_ADJUSTMENT(adjustmenth)->page_size = pageWidth;
		gtk_adjustment_changed(GTK_ADJUSTMENT(adjustmenth));
		modified = true;
	}
	return modified;
}

void ScintillaGTK::ReconfigureScrollBars() {
	PRectangle rc = wMain.GetClientPosition();
	Resize(rc.Width(), rc.Height());
}

void ScintillaGTK::NotifyChange() {
	gtk_signal_emit(GTK_OBJECT(sci), scintilla_signals[COMMAND_SIGNAL],
	                Platform::LongFromTwoShorts(GetCtrlID(), SCEN_CHANGE), PWidget(wMain));
}

void ScintillaGTK::NotifyFocus(bool focus) {
	gtk_signal_emit(GTK_OBJECT(sci), scintilla_signals[COMMAND_SIGNAL],
	                Platform::LongFromTwoShorts(GetCtrlID(), focus ? SCEN_SETFOCUS : SCEN_KILLFOCUS), PWidget(wMain));
}

void ScintillaGTK::NotifyParent(SCNotification scn) {
	scn.nmhdr.hwndFrom = PWidget(wMain);
	scn.nmhdr.idFrom = GetCtrlID();
	gtk_signal_emit(GTK_OBJECT(sci), scintilla_signals[NOTIFY_SIGNAL],
	                GetCtrlID(), &scn);
}

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

	NotifyParent(scn);
}

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

	NotifyParent(scn);
}
const char *CharacterSetID(int characterSet);

int ScintillaGTK::KeyDefault(int key, int modifiers) {
	if (!(modifiers & SCI_CTRL) && !(modifiers & SCI_ALT)) {
#if GTK_MAJOR_VERSION >= 2
		char utfVal[4]="\0\0\0";
		wchar_t wcs[2];
		wcs[0] = gdk_keyval_to_unicode(key);
		wcs[1] = 0;
		UTF8FromUCS2(wcs, 1, utfVal, 3);
		if (key <= 0xFE00) {
			if (IsUnicodeMode()) {
				AddCharUTF(utfVal,strlen(utfVal));
				return 1;
			} else {
				const char *source =
					CharacterSetID(vs.styles[STYLE_DEFAULT].characterSet);
				if (*source) {
					iconv_t iconvh = iconv_open("UTF8", source);
					if (iconvh != ((iconv_t)(-1))) {
						char localeVal[4]="\0\0\0";
						char *pin = utfVal;
						size_t inLeft = strlen(utfVal);
						char *pout = localeVal;
						size_t outLeft = sizeof(localeVal);
						size_t conversions = iconv(iconvh, &pin, &inLeft, &pout, &outLeft);
						iconv_close(iconvh);
						if (conversions != ((size_t)(-1))) {
							*pout = '\0';
							for (int i=0; localeVal[i]; i++) {
								AddChar(localeVal[i]);
							}
							return 1;
						}
					}
				}
			}
		}
#endif
		if (key < 256) {
			AddChar(key);
			return 1;
		} 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) {
	copyText.Copy(selectedText.s, selectedText.len);
	gtk_selection_owner_set(GTK_WIDGET(PWidget(wMain)),
				clipboard_atom,
				GDK_CURRENT_TIME);
}

void ScintillaGTK::Copy() {
	if (currentPos != anchor) {
		CopySelectionRange(&copyText);
		gtk_selection_owner_set(GTK_WIDGET(PWidget(wMain)),
		                        clipboard_atom,
		                        GDK_CURRENT_TIME);
#if PLAT_GTK_WIN32
		if (selType == selRectangle) {
			::OpenClipboard(NULL);
			::SetClipboardData(cfColumnSelect, 0);
			::CloseClipboard();
		}
#endif
	}
}

void ScintillaGTK::Paste() {
	gtk_selection_convert(GTK_WIDGET(PWidget(wMain)),
	                      clipboard_atom,
	                      gdk_atom_intern("STRING", FALSE), 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();
		gtk_container_add(GTK_CONTAINER(PWidget(ct.wCallTip)), PWidget(ct.wDraw));
		gtk_signal_connect(GTK_OBJECT(PWidget(ct.wDraw)), "expose_event",
				   GtkSignalFunc(ScintillaGTK::ExposeCT), &ct);
		gtk_signal_connect(GTK_OBJECT(PWidget(ct.wDraw)), "button_press_event",
				   GtkSignalFunc(ScintillaGTK::PressCT), static_cast<void *>(this));
		gtk_widget_set_events(PWidget(ct.wDraw),
			GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK);
	}
	gtk_drawing_area_size(GTK_DRAWING_AREA(PWidget(ct.wDraw)),
	                      rc.Width(), rc.Height());
	ct.wDraw.Show();
	ct.wCallTip.Show();
	//gtk_widget_set_usize(PWidget(ct.wCallTip), rc.Width(), rc.Height());
	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) {
		primarySelection = true;
		gtk_selection_owner_set(GTK_WIDGET(PWidget(wMain)),
		                        GDK_SELECTION_PRIMARY, GDK_CURRENT_TIME);
		primary.Set(0, 0);
	} else if (OwnPrimarySelection()) {
		primarySelection = true;
		if (primary.s == NULL)
			gtk_selection_owner_set(NULL, GDK_SELECTION_PRIMARY, GDK_CURRENT_TIME);
	} else {
		primarySelection = false;
		primary.Set(0, 0);
	}
}

char *ScintillaGTK::GetGtkSelectionText(const GtkSelectionData *selectionData,
	unsigned int* len, bool* isRectangular) {
	char *dest;
	unsigned int i;
	const char *sptr;
	char *dptr;

	// Return empty string if selection is not a string
	if (selectionData->type != GDK_TARGET_STRING) {
		dest = new char[1];
		strcpy(dest, "");
		*isRectangular = false;
		*len = 0;
		return dest;
	}

	// Need to convert to correct newline form for this file: win32gtk *always* returns
	// only \n line delimiter from clipboard, and linux/unix gtk may also not send the
	// form that matches the document (this is probably not effectively standardized by X)
	dest = new char[(2 * static_cast<unsigned int>(selectionData->length)) + 1];
	sptr = reinterpret_cast<const char *>(selectionData->data);
	dptr = dest;
	for (i = 0; i < static_cast<unsigned int>(selectionData->length) && *sptr != '\0'; i++) {
		if (*sptr == '\n' || *sptr == '\r') {
			if (pdoc->eolMode == SC_EOL_CR) {
				*dptr++ = '\r';
			}
			else if (pdoc->eolMode == SC_EOL_LF) {
				*dptr++ = '\n';
			}
			else { // pdoc->eolMode == SC_EOL_CRLF
				*dptr++ = '\r';
				*dptr++ = '\n';
			}
			if (*sptr == '\r' && i+1 < static_cast<unsigned int>(selectionData->length) && *(sptr+1) == '\n') {
				i++;
				sptr++;
			}
			sptr++;
		}
		else {
			*dptr++ = *sptr++;
		}
	}
	*dptr++ = '\0';

	*len = (dptr - dest) - 1;

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

void ScintillaGTK::ReceivedSelection(GtkSelectionData *selection_data) {
	if (selection_data->type == GDK_TARGET_STRING) {
		//Platform::DebugPrintf("Received String Selection %x %d\n", selection_data->selection, selection_data->length);
		if (((selection_data->selection == clipboard_atom) ||
		        (selection_data->selection == GDK_SELECTION_PRIMARY)) &&
		        (selection_data->length > 0)) {
			unsigned int len;
			bool isRectangular;
			char *ptr = GetGtkSelectionText(selection_data, &len, &isRectangular);

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

			if (isRectangular) {
				PasteRectangular(selStart, ptr, len);
			} else {
				pdoc->InsertString(currentPos, ptr, len);
				SetEmptySelection(currentPos + len);
			}
			pdoc->EndUndoAction();
			delete []ptr;
		}
	}
	Redraw();
}

void ScintillaGTK::ReceivedDrop(GtkSelectionData *selection_data) {
	dragWasDropped = true;
	if (selection_data->type == GDK_TARGET_STRING) {
		if (selection_data->length > 0) {
			unsigned int len;
			bool isRectangular;
			char *ptr = GetGtkSelectionText(selection_data, &len, &isRectangular);
			DropAt(posDrop, ptr, false, isRectangular);
			delete []ptr;
		}
	} else {
		char *ptr = reinterpret_cast<char *>(selection_data->data);
		NotifyURIDropped(ptr);
	}
	Redraw();
}

void ScintillaGTK::GetSelection(GtkSelectionData *selection_data, guint info, SelectionText *text) {
	if (selection_data->selection == GDK_SELECTION_PRIMARY) {
		if (primary.s == NULL) {
			CopySelectionRange(&primary);
		}
		text = &primary;
	}

	char *selBuffer = text->s;

#if PLAT_GTK_WIN32
	// win32gtk requires \n delimited lines and doesn't work right with
	// other line formats, so make a copy of the clip text now with
	// newlines converted
	char *tmpstr = new char[text->len + 1];
	char *sptr = selBuffer;
	char *dptr = tmpstr;
	while (*sptr != '\0') {
		if (pdoc->eolMode == SC_EOL_CR && *sptr == '\r') {
			*dptr++ = '\n';
			sptr++;
		}
		else if (pdoc->eolMode != SC_EOL_CR && *sptr == '\r') {
			sptr++;
		}
		else {
			*dptr++ = *sptr++;
		}
	}
	*dptr = '\0';
	selBuffer = tmpstr;
#endif

	if (info == TARGET_STRING) {
		int len = strlen(selBuffer);
		// 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, GDK_SELECTION_TYPE_STRING,
		                       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);
		gtk_selection_data_set(selection_data, encoding, format, text, new_length);
		gdk_free_compound_text(text);
	}

#if PLAT_GTK_WIN32
	delete []tmpstr;
#endif
}

void ScintillaGTK::UnclaimSelection(GdkEventSelection *selection_event) {
	//Platform::DebugPrintf("UnclaimSelection\n");
	if (selection_event->selection == GDK_SELECTION_PRIMARY) {
		//Platform::DebugPrintf("UnclaimPrimarySelection\n");
		if (!OwnPrimarySelection()) {
			primary.Set(0, 0);
			primarySelection = false;

⌨️ 快捷键说明

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