Пример #1
0
void Todo::highlight_note()
{
  Gtk::TextIter start = get_buffer()->get_iter_at_offset(0);
  Gtk::TextIter end = start;
  end.forward_to_end();
  highlight_region(start, end);
}
Пример #2
0
  void PrintNotesNoteAddin::on_begin_print(const Glib::RefPtr<Gtk::PrintContext>& context)
  {
    m_timestamp_footer = create_layout_for_timestamp(context);
    // Create and initialize the page margins
    m_margin_top = cm_to_pixel (1.5, context->get_dpi_y());
    m_margin_left = cm_to_pixel (1, context->get_dpi_x());
    m_margin_right = cm_to_pixel (1, context->get_dpi_x());
    m_margin_bottom = 0;
    double max_height = pango_units_from_double(context->get_height()
                                                - m_margin_top - m_margin_bottom
                                                - compute_footer_height(context));

    DBG_OUT("margins = %d %d %d %d", m_margin_top, m_margin_left,
            m_margin_right, m_margin_bottom);

    m_page_breaks.clear();

    Gtk::TextIter position;
    Gtk::TextIter end_iter;
    get_buffer()->get_bounds (position, end_iter);

    double page_height = 0;
    bool done = position.compare (end_iter) >= 0;
    while (!done) {
      Gtk::TextIter line_end = position;
      if (!line_end.ends_line ()) {
        line_end.forward_to_line_end ();
      }

      int paragraph_number = position.get_line();
      int indentation = 0;
      Glib::RefPtr<Pango::Layout> layout = create_layout_for_paragraph(
        context, position, line_end, indentation);

      Pango::Rectangle ink_rect;
      Pango::Rectangle logical_rect;
      for(int line_in_paragraph = 0;  line_in_paragraph < layout->get_line_count();
          line_in_paragraph++) {
        Glib::RefPtr<Pango::LayoutLine> line = layout->get_line(line_in_paragraph);
        line->get_extents (ink_rect, logical_rect);

        if ((page_height + logical_rect.get_height()) >= max_height) {
          PageBreak(paragraph_number, line_in_paragraph);
          m_page_breaks.push_back (PageBreak(paragraph_number, line_in_paragraph));
          page_height = 0;
        }

        page_height += logical_rect.get_height();

      }
      position.forward_line ();
      done = position.compare (end_iter) >= 0;
    }

    m_print_op->set_n_pages(m_page_breaks.size() + 1);
  }
Пример #3
0
bool TableofcontentsNoteAddin::has_tag_over_range (Glib::RefPtr<Gtk::TextTag> tag, Gtk::TextIter start, Gtk::TextIter end)
//return true if tag is set from start to end
{
    bool has = false;
    Gtk::TextIter iter = start;
    while (iter.compare(end) != 0 && (has = iter.has_tag(tag))) {
        iter.forward_char();
    }
    return has;
}
Пример #4
0
void Todo::highlight_region(Gtk::TextIter start, Gtk::TextIter end)
{
  if(!start.starts_line()) {
    start.backward_line();
  }
  if(!end.ends_line()) {
    end.forward_line();
  }

  FOREACH(const std::string & pattern, s_todo_patterns) {
    highlight_region(pattern, start, end);
  }    
Пример #5
0
bool is_whitespace(Gtk::TextIter& iter) {
    for(auto ch: std::string("\t\v\f ")) {
        if(iter.get_char() == (gunichar) ch) {
            return true;
        }
    }

    return false;
}
Пример #6
0
void FindBar::locate_matches(const unicode& string) {
    matches_.clear();
    last_selected_match_ = -1;

    auto buf = window_.current_buffer()->buffer();
    auto start = buf->begin();
    Gtk::TextIter end;

    bool case_sensitive = case_sensitive_->get_active();

    while(start.forward_search(
              string.encode(), (case_sensitive) ? Gtk::TextSearchFlags(0) : Gtk::TEXT_SEARCH_CASE_INSENSITIVE,
              start, end)) {

        matches_.push_back(std::make_pair(start, end));
        start = buf->get_iter_at_offset(end.get_offset());
    }

}
Пример #7
0
  Glib::RefPtr<Pango::Layout> 
  PrintNotesNoteAddin::create_layout_for_paragraph(const Glib::RefPtr<Gtk::PrintContext> & context, 
                                                   Gtk::TextIter p_start,
                                                   Gtk::TextIter p_end,
                                                   int & indentation)
  {
    Glib::RefPtr<Pango::Layout> layout = context->create_pango_layout();

    layout->set_font_description(
      get_window()->editor()->get_pango_context()->get_font_description());
    int start_index = p_start.get_line_index();
    indentation = 0;

    double dpiX = context->get_dpi_x();
    {
      Pango::AttrList attr_list;

      Gtk::TextIter segm_start = p_start;
      Gtk::TextIter segm_end;

      while (segm_start.compare (p_end) < 0) {
        segm_end = segm_start;
        std::list<Pango::Attribute> attrs;
        get_paragraph_attributes (layout, dpiX, indentation,
                                  segm_end, p_end, attrs);

        guint si = (guint) (segm_start.get_line_index() - start_index);
        guint ei = (guint) (segm_end.get_line_index() - start_index);

        for(std::list<Pango::Attribute>::iterator iter = attrs.begin();
            iter != attrs.end(); ++iter) {
          
          Pango::Attribute & a(*iter);
          a.set_start_index(si);
          a.set_end_index(ei);
          attr_list.insert(a);
        }
        segm_start = segm_end;
      }

      layout->set_attributes(attr_list);
    }

    gnote::DepthNoteTag::Ptr depth = get_buffer()->find_depth_tag(p_start);
    if(depth) {
        indentation += ((int) (dpiX / 3)) * depth->get_depth();
    }
    layout->set_width(pango_units_from_double((int)context->get_width() -
                                              m_margin_left - m_margin_right - indentation));
    layout->set_wrap (Pango::WRAP_WORD_CHAR);
    layout->set_text (get_buffer()->get_slice (p_start, p_end, false));
    return layout;
  }
Пример #8
0
void FindBar::replace_text(Gtk::TextIter& start, Gtk::TextIter& end, Glib::ustring& replacement) {
    auto buf = window_.current_buffer()->buffer();

    if(buf->get_slice(start, end) == replacement) {
        return;
    }

    //Store the offset to the start of the selection set to be replaced
    auto offset = start.get_offset();

    //Erase the selection
    buf->erase(start, end);

    //Build a new iterator from the stored offset, and insert the text there
    auto new_start = buf->get_iter_at_offset(offset);
    buf->insert(new_start, replacement);
}
Пример #9
0
int32_t FindBar::find_next_match(const Gtk::TextIter& start) {
    if(matches_.empty()) {
        return -1;
    }

    int i = 0;
    for(auto match: matches_) {
        if(match.first.get_offset() > start.get_offset()) {
            return i;
        }
        ++i;
    }

    //If we got here then there were no matches after the cursor, so just return the first one out
    //of all of them
    return 0;
}
Пример #10
0
	void update_cursor_position(const Gtk::TextIter& Iterator, const Glib::RefPtr<Gtk::TextMark>& Mark)
	{
		if(Mark->get_name() != "insert")
			return;

		m_cursor_position.set_text(k3d::string_cast(boost::format(_("Line: %1% Column: %2%")) % (Iterator.get_line() + 1) % (Iterator.get_visible_line_offset() + 1)));
	}
Пример #11
0
  void PrintNotesNoteAddin::on_draw_page(const Glib::RefPtr<Gtk::PrintContext>& context, guint page_nr)
  {
    Cairo::RefPtr<Cairo::Context> cr = context->get_cairo_context();
    cr->move_to (m_margin_left, m_margin_top);

    PageBreak start;
    if (page_nr != 0) {
      start = m_page_breaks [page_nr - 1];
    }

    PageBreak end(-1, -1);
    if (m_page_breaks.size() > page_nr) {
      end = m_page_breaks [page_nr];
    }

    Gtk::TextIter position;
    Gtk::TextIter end_iter;
    get_buffer()->get_bounds (position, end_iter);

    // Fast-forward to the starting line
    while (position.get_line() < start.get_paragraph()) {
      position.forward_line ();
    }

    bool done = position.compare (end_iter) >= 0;
    while (!done) {
      Gtk::TextIter line_end = position;
      if (!line_end.ends_line ()) {
        line_end.forward_to_line_end ();
      }


      int paragraph_number = position.get_line();
      int indentation;

      {
        Glib::RefPtr<Pango::Layout> layout =
          create_layout_for_paragraph (context,position, line_end, indentation);

        for(int line_number = 0;
            line_number < layout->get_line_count() && !done;
            line_number++) {
          // Skip the lines up to the starting line in the
          // first paragraph on this page
          if ((paragraph_number == start.get_paragraph()) &&
              (line_number < start.get_line())) {
            continue;
          }
          // Break as soon as we hit the end line
          if ((paragraph_number == end.get_paragraph()) &&
              (line_number == end.get_line())) {
            done = true;
            break;
          }



          Glib::RefPtr<Pango::LayoutLine> line = layout->get_line(line_number);
          
          Pango::Rectangle ink_rect;
          Pango::Rectangle logical_rect;
          line->get_extents (ink_rect, logical_rect);

          double curX, curY;
          cr->get_current_point(curX, curY);
          cr->move_to (m_margin_left + indentation, curY);
          int line_height = pango_units_to_double(logical_rect.get_height());

          double x, y;
          x = m_margin_left + indentation;
          cr->get_current_point(curX, curY);
          y = curY + line_height;
          pango_cairo_show_layout_line(cr->cobj(), line->gobj());
          cr->move_to(x, y);
        }
      }

      position.forward_line ();
      done = done || (position.compare (end_iter) >= 0);
    }

    // Print the footer
    int total_height = context->get_height();
    int total_width = context->get_width();
    int footer_height = 0;

    double footer_anchor_x, footer_anchor_y;

    {
      Glib::RefPtr<Pango::Layout> pages_footer 
        = create_layout_for_pagenumbers (context, page_nr + 1, 
                                         m_page_breaks.size() + 1);

      Pango::Rectangle ink_footer_rect;
      Pango::Rectangle logical_footer_rect;
      pages_footer->get_extents(ink_footer_rect, logical_footer_rect);
      
      footer_anchor_x = cm_to_pixel(0.5, context->get_dpi_x());
      footer_anchor_y = total_height - m_margin_bottom;
      footer_height = pango_units_to_double(logical_footer_rect.get_height());
      
      cr->move_to(total_width - pango_units_to_double(logical_footer_rect.get_width()) - cm_to_pixel(0.5, context->get_dpi_x()), footer_anchor_y);
                                                      
      pango_cairo_show_layout_line(cr->cobj(), 
                                   (pages_footer->get_line(0))->gobj());

    }

    cr->move_to(footer_anchor_x, footer_anchor_y);
    pango_cairo_show_layout_line(cr->cobj(), 
                                 (m_timestamp_footer->get_line(0))->gobj());

    cr->move_to(cm_to_pixel(0.5, context->get_dpi_x()), 
                total_height - m_margin_bottom - footer_height);
    cr->line_to(total_width - cm_to_pixel(0.5, context->get_dpi_x()),
                total_height - m_margin_bottom - footer_height);
    cr->stroke();
  }
Пример #12
0
  void PrintNotesNoteAddin::get_paragraph_attributes(const Glib::RefPtr<Pango::Layout> & layout,
                                                     double dpiX, 
                                                     int & indentation,
                                                     Gtk::TextIter & position, 
                                                     const Gtk::TextIter & limit,
                                                     std::list<Pango::Attribute> & attributes)
  {
    attributes.clear();
    indentation = 0;

    Glib::SListHandle<Glib::RefPtr<Gtk::TextTag> > tags = position.get_tags();
    position.forward_to_tag_toggle(Glib::RefPtr<Gtk::TextTag>(NULL));
    if (position.compare (limit) > 0) {
      position = limit;
    }

    Glib::RefPtr<Gdk::Screen> screen = get_window()->get_screen();
    double screen_dpiX = screen->get_width_mm() * 254 / screen->get_width();

    for(Glib::SListHandle<Glib::RefPtr<Gtk::TextTag> >::const_iterator iter = tags.begin();
        iter != tags.end(); ++iter) {
      
      Glib::RefPtr<Gtk::TextTag> tag(*iter);

      if (tag->property_paragraph_background_set()) {
        Gdk::Color color = tag->property_paragraph_background_gdk();
        attributes.push_back(Pango::Attribute::create_attr_background(
                               color.get_red(), color.get_green(),
                               color.get_blue()));
      }
      if (tag->property_foreground_set()) {
        Gdk::Color color = tag->property_foreground_gdk();;
        attributes.push_back(Pango::Attribute::create_attr_foreground(
                               color.get_red(), color.get_green(), 
                               color.get_blue()));
      }
      if (tag->property_indent_set()) {
        layout->set_indent(tag->property_indent());
      }
      if (tag->property_left_margin_set()) {                                        
        indentation = (int)(tag->property_left_margin() / screen_dpiX * dpiX);
      }
      if (tag->property_right_margin_set()) {
        indentation = (int)(tag->property_right_margin() / screen_dpiX * dpiX);
      }
//      if (tag->property_font_desc()) {
      attributes.push_back(
        Pango::Attribute::create_attr_font_desc (tag->property_font_desc()));
//      }
      if (tag->property_family_set()) {
        attributes.push_back(
          Pango::Attribute::create_attr_family (tag->property_family()));
      }
      if (tag->property_size_set()) {
        attributes.push_back(Pango::Attribute::create_attr_size (
                               tag->property_size()));
      }
      if (tag->property_style_set()) {
        attributes.push_back(Pango::Attribute::create_attr_style (
                               tag->property_style()));
      }
      if (tag->property_underline_set() 
          && tag->property_underline() != Pango::UNDERLINE_ERROR) {
        attributes.push_back(
          Pango::Attribute::create_attr_underline (
            tag->property_underline()));
      }
      if (tag->property_weight_set()) {
        attributes.push_back(
          Pango::Attribute::create_attr_weight(
            Pango::Weight(tag->property_weight().get_value())));
      }
      if (tag->property_strikethrough_set()) {
        attributes.push_back(
          Pango::Attribute::create_attr_strikethrough (
            tag->property_strikethrough()));
      }
      if (tag->property_rise_set()) {
        attributes.push_back(Pango::Attribute::create_attr_rise (
                               tag->property_rise()));
      }
      if (tag->property_scale_set()) {
        attributes.push_back(Pango::Attribute::create_attr_scale (
                               tag->property_scale()));
      }
      if (tag->property_stretch_set()) {
        attributes.push_back(Pango::Attribute::create_attr_stretch (
                               tag->property_stretch()));
      }
    }
  }
GscHelpWindow::GscHelpWindow(BaseObjectType* gtkcobj, const app_ui_res_ref_t& ref_ui)
		: AppUIResWidget<GscHelpWindow, false>(gtkcobj, ref_ui), selection_callback_enabled(true)
{
	// Connect callbacks

	APP_GTKMM_CONNECT_VIRTUAL(delete_event);  // make sure the event handler is called

	Gtk::Button* window_close_button = 0;
	APP_UI_RES_AUTO_CONNECT(window_close_button, clicked);


	// Accelerators

	Glib::RefPtr<Gtk::AccelGroup> accel_group = this->get_accel_group();
	if (window_close_button) {
		window_close_button->add_accelerator("clicked", accel_group, GDK_Escape,
				Gdk::ModifierType(0), Gtk::AccelFlags(0));
	}


	// --------------- Make a treeview

	Gtk::TreeView* treeview = this->lookup_widget<Gtk::TreeView*>("topics_treeview");
	if (treeview) {
		Gtk::TreeModelColumnRecord model_columns;
		int num_tree_cols = 0;

		// Topic
		model_columns.add(col_topic);
		num_tree_cols = app_gtkmm_create_tree_view_column(col_topic, *treeview, "Topic", "Topic");

		// create a TreeModel (ListStore)
		list_store = Gtk::ListStore::create(model_columns);
		treeview->set_model(list_store);

		selection = treeview->get_selection();
		selection->signal_changed().connect(sigc::mem_fun(*this,
				&self_type::on_tree_selection_changed) );

	}


	// --------------- Parse help text

	/*
	README.txt File Format

	The whole text is converted to unix newline format before parsing.
	Sections are separated by 3 newlines (two empty lines).
	The first line of the section is its header.
	When splitting the file to sections and headers, any leading or trailing
		whitespace is removed.
	If there is a single newline inside a section, it is converted to
		space to enable correct wrapping.
	If there are two consequent newlines, they are left as they are,
		essentially making a paragraph break.
	*/

	std::string readme = hz::string_any_to_unix_copy(ReadmeTextResData().get_string());

	// split by double-newlines

	std::vector<std::string> topics;
	hz::string_split(readme, "\n\n\n", topics, true);  // skip empty


	// add to treeview and textview

	Gtk::TextView* content = this->lookup_widget<Gtk::TextView*>("content_textview");

	if (treeview && content) {
		Glib::RefPtr<Gtk::TextBuffer> buffer = content->get_buffer();

		buffer->create_mark("Begin", buffer->begin(), true);

		for (unsigned int i = 0; i < topics.size(); ++i) {
			std::string topic = hz::string_trim_copy(topics[i]);

			// The first line of topic is its title
			std::vector<std::string> topic_split;
			hz::string_split(topic, "\n\n", topic_split, true, 2);  // skip empty, get 2 elements only

			if (topic_split.size() < 2) {
				debug_out_warn("app", DBG_FUNC_MSG << "Cannot extract topic title in topic " << i << "\n");
				continue;
			}

			std::string topic_title = hz::string_trim_copy(topic_split[0]);
			std::string topic_body = hz::string_trim_copy(topic_split[1]);

			buffer->create_mark(topic_title, buffer->end(), true);  // set topic mark to the end of what's there

			// add the title and make it bold
			buffer->insert(buffer->end(), "\n" + topic_title);

			Gtk::TextIter first = buffer->end(), last = first;
			first.backward_lines(1);

			Glib::RefPtr<Gtk::TextTag> tag = buffer->create_tag();
			tag->property_weight() = Pango::WEIGHT_BOLD;
			tag->property_size_points() = 14;

			buffer->apply_tag(tag, first, last);

			// add the rest

			// single newlines to spaces, to allow proper wrapping.
			app_pcre_replace("/([^\\n])\\n([^\\n])/", "\\1 \\2", topic_body);
			buffer->insert(buffer->end(), "\n\n" + topic_body + "\n\n");


			// Add to treeview

			Gtk::TreeRow row = *(list_store->append());
			row[col_topic] = topic_title;

		}

	}


	// ---------------


	// show();
}
Пример #14
0
    //
    // DND Drop handling
    //
  void NoteEditor::on_drag_data_received(const Glib::RefPtr<Gdk::DragContext> & context,
                                         int x, int y,
                                         const Gtk::SelectionData & selection_data,
                                         guint info,  guint time)
  {
    bool has_url = false;

    std::vector<std::string> targets = context->list_targets();
    for(std::vector<std::string>::const_iterator iter = targets.begin();
        iter != targets.end(); ++iter) {
      const std::string & target(*iter);
      if (target == "text/uri-list" ||
          target == "_NETSCAPE_URL") {
        has_url = true;
        break;
      }
    }

    if (has_url) {
      utils::UriList uri_list(selection_data);
      bool more_than_one = false;

      // Place the cursor in the position where the uri was
      // dropped, adjusting x,y by the TextView's VisibleRect.
      Gdk::Rectangle rect;
      get_visible_rect(rect);
      int adjustedX = x + rect.get_x();
      int adjustedY = y + rect.get_y();
      Gtk::TextIter cursor;
      get_iter_at_location (cursor, adjustedX, adjustedY);
      get_buffer()->place_cursor (cursor);

      Glib::RefPtr<Gtk::TextTag> link_tag = get_buffer()->get_tag_table()->lookup ("link:url");

      for(utils::UriList::const_iterator iter = uri_list.begin();
          iter != uri_list.end(); ++iter) {
        const sharp::Uri & uri(*iter);
        DBG_OUT("Got Dropped URI: %s", uri.to_string().c_str());
        std::string insert;
        if (uri.is_file()) {
          // URL-escape the path in case
          // there are spaces (bug #303902)
          insert = sharp::Uri::escape_uri_string(uri.local_path());
        } 
        else {
          insert = uri.to_string ();
        }

        if (insert.empty() || sharp::string_trim(insert).empty())
          continue;

        if (more_than_one) {
          cursor = get_buffer()->get_iter_at_mark (get_buffer()->get_insert());

          // FIXME: The space here is a hack
          // around a bug in the URL Regex which
          // matches across newlines.
          if (cursor.get_line_offset() == 0) {
            get_buffer()->insert (cursor, " \n");
          }
          else {
            get_buffer()->insert (cursor, ", ");
          }
        }

        get_buffer()->insert_with_tag(cursor, insert, link_tag);
        more_than_one = true;
      }

      context->drag_finish(more_than_one, false, time);
    } 
    else {
      Gtk::TextView::on_drag_data_received (context, x, y, selection_data, info, time);
    }
  }